Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.02.2015, 19:00   #1
isst
Пользователь
 
Регистрация: 02.01.2015
Сообщений: 85
Сообщение Ближайшее число (Матрица)

Всем доброго времени суток:

Дана матрица A размером NxN, заполненная неотрицательными целыми числами. Расстояние между двумя элементами Ai j и Ap q определено как |i - p| + |j - q|.

Требуется заменить каждый нулевой элемент матрицы ближайшим ненулевым. Если есть две или больше ближайших ненулевых ячейки, нуль должен быть оставлен.

Ограничения: 1 <= N <= 200, 0 <= Ai j <= 1 000 000.

Входные данные
В первой строке содержится число N. Затем идут N строк по N чисел, разделённых пробелами и представляющих собой матрицу.

Выходные данные
Выводится N строк по N чисел, разделённых пробелами, - модифицированная матрица.

Примеры:
входные данные
3
5 0 0
0 0 0
0 0 6
выходные данные
5 5 0
5 0 6
0 6 6

Помогите, пож!
isst вне форума Ответить с цитированием
Старый 07.02.2015, 19:45   #2
FPaul
Форумчанин
 
Регистрация: 25.01.2015
Сообщений: 472
По умолчанию

Судя по условию - задача проверяется ejudge. Ты для себя участвуешь в онлайн-псевдоолимпиадах?

Тут решение ищется вариацией поиска в ширину (BSF) - почти волновым методом (алгоритм Ли). Лишь условия остановки слегка изменяются. В отличие от алгоритма Ли (из-за отсутствия препятствий) можно не хранить список ячеек фронта волны, а вычислять их.

Ознакомиться с алгоритмом Ли можно на Wikipedia и algolist.

Пробуй.
Или ты очень занят, а решать кому-то нужно? Я тоже занят - к нам в город приехал цирк Дю Солей, мы только это и обсуждаем с детьми.
FPaul вне форума Ответить с цитированием
Старый 07.02.2015, 20:19   #3
Poma][a
Новичок
Джуниор
 
Регистрация: 11.10.2011
Сообщений: 3,882
По умолчанию

Я тож за BFS.
Цитата:
В отличие от алгоритма Ли (из-за отсутствия препятствий) можно не хранить список ячеек фронта волны, а вычислять их.
Эм.. Что?
Если не хранить волну, то получим N^4.. А это точно не зайдет

И да, я бы начал так :
Пробежался бы по массиву, ставля перманентные 0
А дальше уже bfs
Poma][a вне форума Ответить с цитированием
Старый 07.02.2015, 20:56   #4
FPaul
Форумчанин
 
Регистрация: 25.01.2015
Сообщений: 472
По умолчанию

А как уменьшить? Ведь, по существу, рассматриваются сочетания всех ячеек со всеми.
А не хранить фронт волны - просто отказ от двух массивов с перечнем ячеек текущей волны и с перечнем ячеек волны следующего шага. Т.к. можно получить аналитический вид 4 циклов for (ну добавив проверки на границы матрицы).
-----
Подумал ещё. Да, лучше хранить. Тогда при "неперспективности" направления будет уменьшаться длина волны=время выполнения.
FPaul вне форума Ответить с цитированием
Старый 07.02.2015, 21:02   #5
Poma][a
Новичок
Джуниор
 
Регистрация: 11.10.2011
Сообщений: 3,882
По умолчанию

Да не.. Ну на кой нам два массива.. Бахнем одну очередь. Будем крутить пока она не пуста, занимая соседние клетки
Poma][a вне форума Ответить с цитированием
Старый 07.02.2015, 21:31   #6
FPaul
Форумчанин
 
Регистрация: 25.01.2015
Сообщений: 472
По умолчанию

Нет да пруф.

Хотя рядом с одним массивом. Но я его не понял - значит его не существует. Нет нет нет. Он, кажется, совсем без массива с волной. Там, что-то другое.
---------------
Ссылкозакидательство вместо аргументов.
FPaul вне форума Ответить с цитированием
Старый 07.02.2015, 21:53   #7
Poma][a
Новичок
Джуниор
 
Регистрация: 11.10.2011
Сообщений: 3,882
По умолчанию

Цитата:
Хотя рядом с одним массивом. Но я его не понял - значит его не существует. Нет нет нет. Он, кажется, совсем без массива с волной. Там, что-то другое.
Оно с очередью..
Poma][a вне форума Ответить с цитированием
Старый 07.02.2015, 22:21   #8
FPaul
Форумчанин
 
Регистрация: 25.01.2015
Сообщений: 472
По умолчанию

Да, точно. Вариант С с очередью - эквивалентом объединения двух массивов (текущий фронт и будущий), но ускоренный из-за отсутствия копирования одного в другой.
Ну для нас всё уже ясно. Осталось уговорить кого-нибудь начать реализацию.
FPaul вне форума Ответить с цитированием
Старый 07.02.2015, 23:00   #9
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Возле каждого нуля делать цикл по концентрическими квадратам под углом 45 градусов с учетом границы матрицы пока не найдется 1 или больше не нулевых в квадрате. В этом квадрате расстояние одинаковое до центра. Все. А то придумали, алгоритм Ли Массив один, забитые нули заполнить отрицательными что бы не путаться, выводить Abs
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 07.02.2015, 23:30   #10
Poma][a
Новичок
Джуниор
 
Регистрация: 11.10.2011
Сообщений: 3,882
По умолчанию

Вот..
Пока так..
Косяк на 8 тесте..
Проверял тут
Код:
#include <fstream>
#include <vector>
#include <queue>

using namespace std;
ifstream cin("input.txt");
ofstream cout("output.txt");


struct st
{
	int x, y, w;	
};

struct _step
{
	int x, y;	
};

_step step[] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

int main() {
	int n;
	cin >> n;
	
	vector<vector<int> > v(n+2, vector<int> (n+2)), p(n+2, vector<int> (n+2, -1)), p1(n+2, vector<int> (n+2, 0));
	queue<st> q;
	int k = 0;
	
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
		{
			cin >> v[i][j];
			if (v[i][j] == 0)
			{
				k++;
				p[i][j] = 0;
			}
			else
			{
				st _t;
				_t.x = i; _t.y = j; _t.w = v[i][j];
				q.push(_t);
				p[i][j] = v[i][j];
			}
		}	
	
	while (!q.empty() && k > 0)
	{
		queue<st> temp;
		vector<vector<int> > p1(n+2, vector<int> (n+2, -1));
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				p1[i][j] = 0;
				
		while (!q.empty())
		{
			st t = q.front();
			q.pop();
			for (int i = 0; i < 4; i++)
				if (p[t.x+step[i].x][t.y+step[i].y] != 0 && p1[t.x+step[i].x][t.y+step[i].y] == p1[t.x][t.y]+1 && p[t.x+step[i].x][t.y+step[i].y] != t.w)
					p[t.x+step[i].x][t.y+step[i].y] = -1;
				else if (p[t.x+step[i].x][t.y+step[i].y] == 0)
				{
					k--;
					p1[t.x+step[i].x][t.y+step[i].y] = p1[t.x][t.y]+1;
					st _t;
					_t.x = t.x+step[i].x; _t.y = t.y+step[i].y; _t.w = t.w;
					temp.push(_t);
					p[t.x+step[i].x][t.y+step[i].y] = t.w;
				}
		
		}
		q = temp;
		
	}
	
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
			cout << max(0, p[i][j]) << " ";
		cout << endl;
	}
	cout << endl;
	return 0;
}
Там вроде много лишнего есть..
Poma][a вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Найти ближайшее к какому - нибудь целому Asya7 Паскаль, Turbo Pascal, PascalABC.NET 8 15.01.2015 02:00
Prolog.Ближайшее значение в списке Lisёноk Помощь студентам 2 28.11.2013 16:36
Ближайшее и наименьшее к n из двух чисел turtles Общие вопросы по Java, Java SE, Kotlin 2 25.08.2011 16:19
Натуральное число n. Матрица lexx007 Помощь студентам 1 20.12.2008 22:35