XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Общение> Трактир
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
Tiodor

offline
Опыт: 75,784
Активность:
Задача: упорядочить
Вот собственно...
мы задаем число N. затем создается двумерный массив а(n,n)
нам нужно сделать вот такую перестановку
числа рандомные
хз как надо это сделать =\
Миниатюры
Кликните на картинку для увеличения
Название:  635.jpg
Просмотров: 62
Размер:  81.9 Кбайт  
Старый 30.03.2012, 14:35
J64_

offline
Опыт: 4,724
Активность:
для таких задач сначала пишем по порядку какие индексы будут использоваться, анализируем, делаем решение для любого N.
иногда решения бывают разными при четном n и нечетном. -> проверяем обе, желательно при больших n. (с) Кэп
для 4x4
3 3, 2 3 x-1
3 2, 3 3 y+1
1 2, 3 2 x+2
1 4, 1 2 y-2
4 4, 1 4 x-3
4 1, 4 4 y+3
1 1, 4 1
для 5x5
3 3, 2 3 x-1
2 3, 2 4 y+1
2 4, 4 4 x+2
4 4, 4 2 y-2
4 2, 1 2 x-3
1 2, 1 5 y+3
1 5, 5 5 x+4
5 5, 5 1 y-4
1 1, 5 1
Как мы видим, разница индексов с каждым разом увеличивается на один, и каждый раз меняется знак операции(плюс, минус). Если смотреть попарно, то количество действий будет равна: 2 * (n - 1) + 1.
Решение на паскале
var
	x, y, n, d, sign: Integer;
	a: array[1..100, 1..100] of Integer;
begin
	sign := -1;
	x := n div 2 + 1;
	y := x;
	for d := 1 to n - 1 do
	begin
		a[x, y] := a[x + d * sign, y];
		x := x + d * sign;
		a[x, y] := a[x, y - d * sign];
		y := y - d * sign;
		sign := -sign;
	end;
	a[n, 1] := a[1, 1];
end;
Старый 30.03.2012, 17:26
ScorpioT1000
Работаем
offline
Опыт: отключен
Вот еще логическое решение, если надо:
void SpiralTraversal(size_t min, size_t max) {
	size_t x = min;
	size_t y = min;
	size_t oldx = 0xFFFFFFFF; // это лишнее
	size_t oldy = 0xFFFFFFFF; // это лишнее
	int old = spiralmx[min][min];
	int temp = 0;
	bool newSpire = false;
	
	while(1) {
		Sleep(250); // это лишнее
		SpiralPrint(x,y,oldx,oldy); // это лишнее

		if( (y == min || y == max) && (x == min || x == max) ) { 
			// если в любом из углов, запоминаем
			oldx = x; // это лишнее
			oldy = y; // это лишнее
			// задаем на новом месте значение старого и меняем местами старое с новым
			temp = spiralmx[x][y];
			spiralmx[x][y] = old;
			old = temp;
			Sleep(250); // это лишнее
			SpiralPrint(x,y,oldx,oldy); // это лишнее
		}

		if(y == min && x != max) { // едем по верхнему краю вправо ->
			x++;
		} else if(x == max && y != max) { // едем по правому краю вниз V
			y++;
		} else if(y == max && x != min) { // едем по нижнему краю влево <-
			x--;
		} else if(x == min) { // едем по левому краю вверх ^
			if(y == min+1) { // лево верх, переход на новый виток
				max--;
				min++;
			} else {
				y--;
			}
		} else {
			return;
		}

		if(min >= max) {
			return; // конец
		}
	}
	
}
Тока там косяк - он заменяет соседнюю ячейку при переходе на новый виток =\ потом доделаю) если надо...
» Весь код
#include <iostream>
#include <conio.h>
#include <time.h>
#include <windows.h>
using namespace std;


const size_t g_min = 0;
const size_t g_max = 8;
const size_t g_size = g_max + 1;
int spiralmx[g_size][g_size];

void SpiralFillRandom() {
	size_t x = g_min;
	size_t y = g_min;
	srand((unsigned int)time(0));
	while(x <= g_max) {
		y = g_min;
		while(y <= g_max) {
			spiralmx[x][y] = rand() % 1000;
			y++;
		}
		x++;
	}
}

void SpiralPrint(size_t xsel = 0xFFFFFFFF, size_t ysel = 0xFFFFFFFF, size_t xsel2 = 0xFFFFFFFF, size_t ysel2 = 0xFFFFFFFF) {
	size_t x;
	size_t y = g_min;
	system("cls");
	cout << "SpiralTraversal:\n";
	while(y <= g_max) {
		x = g_min;
		while(x <= g_max) {
			if(xsel == x && ysel == y) {
				cout << "[";
			} else if(xsel2 == x && ysel2 == y) {
				cout << "-";
			} else {
				cout << " ";
			}
			cout << spiralmx[x][y];
			if(xsel == x && ysel == y) {
				cout << "]";
			} else if(xsel2 == x && ysel2 == y) {
				cout << "-";
			} else {
				cout << " ";
			}
			cout <<  "\t";
			x++;
		}
		cout << endl;
		y++;
	}
}

void SpiralTraversal(size_t min, size_t max) {
	size_t x = min;
	size_t y = min;
	size_t oldx = 0xFFFFFFFF; // это лишнее
	size_t oldy = 0xFFFFFFFF; // это лишнее
	int old = spiralmx[min][min];
	int temp = 0;
	bool newSpire = false;
	
	while(1) {
		Sleep(250); // это лишнее
		SpiralPrint(x,y,oldx,oldy); // это лишнее

		if( (y == min || y == max) && (x == min || x == max) ) { 
			// если в любом из углов, запоминаем
			oldx = x; // это лишнее
			oldy = y; // это лишнее
			// задаем на новом месте значение старого и меняем местами старое с новым
			temp = spiralmx[x][y];
			spiralmx[x][y] = old;
			old = temp;
			Sleep(250); // это лишнее
			SpiralPrint(x,y,oldx,oldy); // это лишнее
		}

		if(y == min && x != max) { // едем по верхнему краю вправо ->
			x++;
		} else if(x == max && y != max) { // едем по правому краю вниз V
			y++;
		} else if(y == max && x != min) { // едем по нижнему краю влево <-
			x--;
		} else if(x == min) { // едем по левому краю вверх ^
			if(y == min+1) { // лево верх, переход на новый виток
				max--;
				min++;
			} else {
				y--;
			}
		} else {
			return;
		}

		if(min >= max) {
			return; // конец
		}
	}
	
}



void main() {
	SpiralFillRandom();
	cout << "Hello and vodka from ScorpioT1000! Press any key:\n";
	_getch();
	SpiralTraversal(g_min, g_max);

	_getch();
}
Прикрепленные файлы
Тип файла: zip DEMO_SpiralForTiodor.zip (4.2 Кбайт, 0 просмотров )
Старый 30.03.2012, 17:44
Tiodor

offline
Опыт: 75,784
Активность:
x := n div 2 + 1;
как это в бейсике ввести, чет я туплю =\
Tiodor добавил:
уже нашел
Judycaster64, сверху созданная матрица
внизу упорядоченная
=\
Миниатюры
Кликните на картинку для увеличения
Название:  639.jpg
Просмотров: 26
Размер:  53.6 Кбайт  
Старый 30.03.2012, 18:02
J64_

offline
Опыт: 4,724
Активность:
Tiodor, это задание №2, или это моих рук дело?
Старый 30.03.2012, 18:26
Tiodor

offline
Опыт: 75,784
Активность:
п.с. это по твоему коду
Старый 30.03.2012, 18:26
J64_

offline
Опыт: 4,724
Активность:
Tiodor, хз что там ты у себя в бэйсике наделал, но код выше, при нечетных n, работает как часы, а при четном n неправильно работал. Исправил
var
	x, y, n, d, sign: Integer;
	a: array[1..100, 1..100] of Integer;
begin
	if(n mod 2 = 0)then
	begin
		x := n div 2;
		y := x + 1;
		sign := 1;
	end else
	begin
		x := n div 2 + 1;
		y := x;
		sign := -1;
	end;
	for d := 1 to n - 1 do
	begin
		a[x, y] := a[x + d * sign, y];
		x := x + d * sign;
		a[x, y] := a[x, y - d * sign];
		y := y - d * sign;
		sign := -sign;
	end;
	a[n, 1] := a[1, 1];
end.
Старый 30.03.2012, 19:25
Tiodor

offline
Опыт: 75,784
Активность:
Judycaster64, хз, все писал как у тебя
попробую вечером этот код
Tiodor добавил:
все равно не работает, я хз или ты понял как оно должно работать =\
a[n, 1] := a[1, 1];
что оно делает? =\ оно меняет левый нижний элемент на первый элемент
Tiodor добавил:
да и некоторые элементы оно меняет в другую сторону...
ну то есть должно по часовой стрелке, а оно меняет против
Старый 30.03.2012, 22:49
WaterMan
J.R.R.
offline
Опыт: 17,019
Активность:
Самое простое и очевидное решение (не рациональное вроде, хз, ты максимум не указал) на паскале:
» жми
var
a:array[1..1000,1..1000] of longint;
b:array[1..1000,1..1000] of boolean;
i,j,n:longint;
c,d:integer;

begin
assign(input,'input.txt');
reset(input);
assign(output,'output.txt');
rewrite(output);
fillchar(b,sizeof(b),false);
readln(n);
for i:=1 to n do
 for j:=1 to n do
  read(a[i,j]);
c:=0; d:=1;
i:=1; j:=1;
while i<>maxlongint do
 begin
  if (i+c>=1) and (j+d>=1) then
   if (b[i+1,j]=true) and (b[i,j+1]=true) and (b[i-1,j]=true) and (b[i,j-1]=true) then
    break;
  b[i,j]:=true;
  write(a[i,j],'; ');
  i:=i+c; j:=j+d;
   if (i+c>=1) and (j+d>=1) then
    if (b[i+c,j+d]=true) or ((j=n) and (i=1)) or ((i=n) and (j=n)) then
     begin
      if (c=0) and (d=1) then begin c:=1; d:=0; continue; end;
      if (c=1) and (d=0) then begin c:=0; d:=-1; continue; end;
      if (c=0) and (d=-1) then begin c:=-1; d:=0; continue; end;
      if (c=-1) and (d=0) then begin c:=0; d:=1; continue; end;
     end;
   if (i=n) and (j=1) then begin c:=-1; d:=0; continue; end;
  end;
write(a[i,j]);
end.
Прилагаю также в скомпилированном виде (в input.txt вводишь размерность массива и элементы, output.txt выведет тебе элементы по порядку). Упорядочивание сделаешь сам, как надо, тут обход только и вывод для наглядности. Если непонятен где-то код - пиши сюда или в аську, разберемся. Попозже выложу описание алгоритма.
В целом, вроде работает нормально, хз насколько отличается от предыдущих решений, особо не заморачивался над придумыванием кода.
Прикрепленные файлы
Тип файла: zip zadacha.zip (22.3 Кбайт, 0 просмотров )
Старый 31.03.2012, 17:21
Tiodor

offline
Опыт: 75,784
Активность:
у меня пока нет возможности искать значения функций, но что значит
maxlongint
fillchar
continue;
Старый 31.03.2012, 18:55
WaterMan
J.R.R.
offline
Опыт: 17,019
Активность:
Tiodor, maxlongint - не функция. Это я так, чтобы зациклить цикл (извиняюсь за тавтологию). Maxlongint - максимальное значение, которое может принимать переменная типа longint (2*10^9), можно вместо нее просто большое число, за пределами максимального размера массива (10^6 мб, хз, как у тебя там максимальные данные в задаче)
fillchar - заполнить массив определенным числом, символом (в данном случае, false'ами). Вообще, это не обязательно зависит от компилятора. Мой компилятор (free pascal) присваивает всем переменным типа boolean (логический, булев тип) по умолчанию false. Но на всякий случай я всегда пишу fillchar.
continue - переход к следующему шагу цикла. То есть, в данном случае он просто возвращается к началу цикла. Это сделано для того, чтобы он следом нижние условия не читал, а вернулся на начало.
WaterMan добавил:
Tiodor, а вообще, ты в алгоритме разобрался и расписать надо?
Старый 31.03.2012, 19:29
Tiodor

offline
Опыт: 75,784
Активность:
WaterMan, лучше распиши и я себе перепишу... потому, что бейсик канешн с паскалем чем-то похож... но все же я скорее запутаюсь
Старый 31.03.2012, 20:59
WaterMan
J.R.R.
offline
Опыт: 17,019
Активность:
Tiodor, примерно так:
Создаем массив логического (булев) типа, который будет хранить номера ячеек, которые мы уже посетили (если мы уже прошли ячейку a[3,4], то в массиве b[3,4] будет храниться true). Заводим переменные c и d, которые хранят в себе смещение для координат массива (c для i, d для j, c=0, d=1, так как сначала пойдем вправо). Делаем бесконечный цикл, который не завершится пока мы его не прервем. В начале цикла проверяем, если из ячейки, в которой мы сейчас находимся нельзя пройти ни влево, ни вправо, ни вверх, ни вниз (то есть, ячейки вокруг были посещены), то цикл завершается. Если же нет, делаем ячейку, в которой мы сейчас находимся посещенной (b[i,j]:=true). Далее меняем координаты текущей ячейки на координаты плюс смещение (i:=i+c, j:=j+d, c и d мы завели вначале). Далее идем в указанном направлении, пока не наткнемся на уже посещенную ячейку либо не выйдем за пределы массива. Как только наткнемся либо выйдем, меняем направление (присваивая переменным c и d новые значения, в коде я укзал, как. Думаю, тут должно быть понятно, если шли вправо, идем вниз, если вниз, идем влево и т.д.). Таким образом, мы дойдем до центра массива, параллельно в цикле можно его упорядочивать или выводить, как угодно, цикл проходит массив именно в нужном порядке.
Все понятно?
Старый 31.03.2012, 21:15
J64_

offline
Опыт: 4,724
Активность:
Tiodor, наверное я не совсем понял тебя, судя по рисунку, тебе ведь нужно чтобы циферка из конца стрелки была впереди?
т.е.
вместо -1 будет 52, вместо 7 -1, вместо 60 7 и так далее...
короче высылаю программу - стандартная, input.txt, output.txt. в первой строке - n, начиная со второй - элементы массива.
Прикрепленные файлы
Тип файла: rar Project1.rar (20.8 Кбайт, 4 просмотров )
Старый 01.04.2012, 07:10
Tiodor

offline
Опыт: 75,784
Активность:
вот что происходит... покажи свой скрин, как оно у тебя
тем более a[n, 1] := a[1, 1];
это команда просто абсурдная
зачем заменять это число?
Tiodor добавил:
сверху изначальная матрица, внизу упорядоченная
29-47-6238-17
-56-36715234
-25182125-13
52-1114-1-1
44525-5413
а вот так должно быть
29-47-623829
44-1171-3634
-25182552-13
52-11452-1
13525-54-17
Миниатюры
Кликните на картинку для увеличения
Название:  641.jpg
Просмотров: 9
Размер:  52.2 Кбайт  
Старый 01.04.2012, 15:34
Tiodor

offline
Опыт: 75,784
Активность:
Вот собственно решение

((код
Option Base 1
Sub Zadacha()
Dim A() As Double
Dim i, j, l, h, n, s, m, n2, m2, p2, q2, nom, nom1, k As Integer
Dim indeks, indeks1, indeks2, indeks3 As Integer
n = InputBox("n")
ReDim A(n, n)
l = InputBox("max")
h = InputBox("min")
For i = 1 To n
For j = 1 To n
A(i, j) = Int((h - l + 1) * Rnd + l)
Cells(i, j).Value = A(i, j)
Next j
Next i
indeks = 1
indeks1 = n
indeks2 = n
indeks3 = 1
n2 = n
m2 = 1
p2 = n
q2 = 2
nom = 0
nom1 = 0
For k = 1 To 2 * n - 1
If k Mod 2 <> 0 Then
nom = nom + 1
If nom Mod 2 <> 0 Then
If q2 > 2 Then
s = A(indeks, n2)
A(indeks, n2) = m
n2 = n2 - 1
indeks = indeks + 1
Else
s = A(indeks, n2)
A(indeks, n2) = A(indeks, 1)
n2 = n2 - 1
indeks = indeks + 1
End If
Else
s = A(indeks1, m2)
A(indeks1, m2) = m
m2 = m2 + 1
indeks1 = indeks1 - 1
End If
Else
nom1 = nom1 + 1
If nom1 Mod 2 <> 0 Then
m = A(p2, indeks2)
A(p2, indeks2) = s
p2 = p2 - 1
indeks2 = indeks2 - 1
Else
m = A(q2, indeks3)
A(q2, indeks3) = s
q2 = q2 + 1
indeks3 = indeks3 + 1
End If
End If
Next k
For i = 1 To n
For j = 1 To n
Cells(i, j + n + 2).Value = A(i, j)
Next j
Next i
End Sub
))

Отредактировано Tiodor, 02.04.2012 в 19:22.
Старый 02.04.2012, 19:16
J64_

offline
Опыт: 4,724
Активность:
Tiodor, ты хоть проверял?
input.txt
5
29 -47 -62 38 -17
-56 -36 71 52 34
-25 18 21 25 -13
52 -11 14 -1 -1
44 5 25 -54 13
output.txt
29 -47 -62 38 29
44 -36 71 -56 34
-25 -11 18 25 -13
52 -1 14 52 -1
13 5 25 -54 -17
где у меня неверно?
тем более a[n, 1] := a[1, 1];
это команда просто абсурдная
зачем заменять это число?
потому что если попарно смотреть, то только эта замена остается(см. в 2 посте). В самую правую ячейку самой верхней строки записывает значение самой левой ячейки самой верхней строки.
и кстати ты упорядоченную таблицу как-то неверно сделал, ну там -56 потерял и т.п. :)
Старый 04.04.2012, 14:14
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 13:13.