Всем привет! требуется написать прогу для заполнения прямоугольной таблицы размерами n*n по спирали числами от 1 до n*n. Я вот тут кое-что написал но работает не так, как надо... Мозги уже кипят... Помогите плиз кто чем может... Хотя бы намёк сделайте=)
Lapp
10.02.2010 11:52
Цитата(Alexdel @ 10.02.2010 11:17)
требуется написать прогу для заполнения прямоугольной таблицы размерами n*n по спирали числами от 1 до n*n. Я вот тут кое-что написал но работает не так, как надо...
По спирали - это от центра? тогда ПО часовой или против? Или скраю к центру? вопрос про направление остается..
А вообще, задача про спираль несколько раз была. Искать не пробовал?
И почему в алгоритмах? Тебе же код нужен или только словесное описание?
Последнее: код не надо прикреплять в файле. Надо вставлять в мессадж с тегами кода (меню CODE над окном ввода).
Lapp
10.02.2010 12:29
Цитата(Alexdel @ 10.02.2010 11:17)
Мозги уже кипят... Помогите плиз кто чем может... Хотя бы намёк сделайте=)
Вот, глянь. Я тут изменил названия переменных. А то, ты в условии говоришь одно, а в решении - другое.. Зачем? Надо стараться сохранять буковки, как они есть.
program task4;
const
m= 20;
var
a: array[1..m, 1..m] of integer;
i,j, n, k: integer;
begin
k:=1;
write('vvedite razmer matricy (ot 1 do ',m,'): ');
ReadLn(n);
for i:=1to (n+1) div2dobegin{исправлено}for j:=i to n-i+1dobegin
a[i,j]:=k;
Inc(k);
end;
for j:=i+1to n-i+1dobegin
a[j,n-i+1]:=k;
Inc(k);
end;
for j:=n-i downto i dobegin
a[n-i+1,j]:=k;
Inc(k);
end;
for j:=n-i downto i+1dobegin
a[j,i]:=k;
Inc(k);
end;
end;
for i:=1to n dobeginfor j:=1to n doWrite(a[i,j]:5);
WriteLn
end;
readln;
end.
М
Тему переношу в Задачи..
Добавлено через 2 мин. Еще одно: тебе пришлось ставить два ReadLn в конце, потому что ты читал входные данные Read'ом, но вводил с энтером. Этот энтер сохранялся и съедал первый ReadLn. Если ввод заканчивается энтером - читай его ReadLn'ом.
Добавлено через 9 мин. Упс!.. Моя прога не заполняет центральный элемент при нечетном n. Сейчас исправим..
Добавлено через 2 мин. Собственно, исправление совсем небольшое. Надо во внешнем цикле верхний предел изменить на (n+1) div 2. Я это сейчас сделаю прямо в том коде..
RathaR
10.02.2010 15:29
Забавно Буквально вчера, сидел в кабинете информатики, пересматривал задания старых олимпиад, и наткнулся на первую(!) олимпиаду по программированию, что проводились у нас, год точно не скажу, девяносто какой то, так это была первая задача в той олимпиаде))) Просто ради интереса сел, сделал её, за урок, правда там матрица прямоугольная была. Вот, собственно, мое решение, особо долго не думал над ней(просто обходил матрицу определяя куда ставить след номер)...
const
max_size=10;
type
tMove=(up,down,left,right);
var
m,n:integer;
A:array[0..max_size+1,0..max_size] of integer;
I:integer;
K:integer;
x,y:integer;
procedure Input(var x,y:integer);
var
F1:text;
begin
assign(F1,'spiral.dat');
reset(F1);
read(F1,N,M);
close(F1);
end;
procedure Output;
var
I,J:integer;
F2:text;
begin
assign(F2,'spiral.sol');
rewrite(F2);
for I:=0to m+1dobeginfor J:=0to n+1dowrite(F2,A[I,J]:3);
writeln(F2);
end;
close(F2);
end;
function move(x,y:integer):tMove;
var
left_z,right_z,up_z,down_z:boolean;
beginif A[x+1,y]=0then right_z:=true else right_z:=false;
if A[x-1,y]=0then left_z:=true else left_z:=false;
if A[x,y+1]=0then down_z:=true else down_z:=false;
if A[x,y-1]=0then up_z:=true else up_z:=false;
if right_z andnot down_z then move:=right;
if left_z andnot up_z then move:=left;
if up_z andnot right_z then move:=up;
if down_z andnot left_z then move:=down;
end;
begin
Input(m,n);
fillchar(A,sizeof(A),0);
for I:=0to N+1dobegin
A[0,I]:=-1;
A[M+1,I]:=-1;
end;
for I:=0to M+1dobegin
A[I,0]:=-1;
A[I,N+1]:=-1;
end;
K:=1;
x:=m;
y:=1;
A[x,y]:=K;
while K<>m*n dobegincase move(x,y) of
right:begin
inc(K);
inc(x);
A[x,y]:=K;
end;
left:begin
inc(K);
dec(x);
A[x,y]:=K;
end;
up:begin
inc(K);
dec(y);
A[x,y]:=K;
end;
down:begin
inc(K);
inc(y);
A[x,y]:=K;
end; end;
end;
Output;
end.
Заядло я её не тестировал, но вроде работает, файлы прикрепляю.
Lapp
11.02.2010 3:20
Цитата(RathaR @ 10.02.2010 15:29)
сел, сделал её, за урок, правда там матрица прямоугольная была.
За урок такое сделать - респект!
Rathar, идея твоя интересная. Я ее реализовал тут.. Вот, что вышло:
const
max= 20;
var
a: array[1..max, 1..max] of integer;
m,n,i,j,di,dj,b,k: integer;
begin
FillChar(a,SizeOf(a),0); // инициализация, вставлено позже
k:=1;
write('введите количество строк (не больше ',max,'): ');
ReadLn(m);
write('введите количество столбцов (не больше ',max,'): ');
ReadLn(n);
k:=1;
i:=1;
j:=1;
di:=0;
dj:=1;
repeat
a[i,j]:=k;
Inc(k);
if (i+di>m)or(i+di<1)or(j+dj>n)or(j+dj<1)or(a[i+di,j+dj]>0) thenbegin
b:=dj;
dj:=-di;
di:=b
end;
i:=i+di;
j:=j+dj;
until a[i,j]>0;
for i:=1to m dobeginfor j:=1to n doWrite(a[i,j]:5);
WriteLn
end;
readln;
end.
Тут главное - что для смены направления не нужно знать направление. Формулы предельно просты: di = dj dj = -di Проверь их.
Lapp
11.02.2010 10:49
На свежую голову (после работы)) глянул на код и заметил, что так и забыл вставить инициализацию массива, которую почему-то откладывал на потом. Короче, сейчас вставлю..
RathaR
20.10.2010 17:48
Мне эта задача выпала на лабораторную по проге, за тему матриц. Ну это судьба... Совесть не выдержала, сразу показал преподу решение, взял другую лабу
RathaR
2.11.2010 22:31
Сегодня эта задача попалась на тренировке по спортивному програмированию... даж не знаю... задача классическая, никто не спорит, но я, перед окончанием, ради интереса отправил оба решения: Lapp твоя прога на 12 тесте дала неверный результат))) Моя - на шестом
Unconnected
2.11.2010 23:02
Это уже правда судьба ))
А на каких тестах, не показывается там? Хотя, что я спрашиваю... это везде так, wrong answer on test 10, как будто номер теста чем то поможет)
TarasBer
2.11.2010 23:04
> А на каких тестах, не показывается там?
Ну дык, чтобы программист в алгоритме ошибку искал, а не костыли для конкретного случая вбивал.
> как будто номер теста чем то поможет)
Поможет. Маленький номер - значит алгоритм сам по себе лажовый, большой - значит всё правильно, но не разобран какой-то корявый краевой случай.
Lapp
3.11.2010 0:44
Цитата(RathaR @ 2.11.2010 22:31)
задача классическая, никто не спорит
Я спорю. Ни разу еще в этой теме не появилось условие! Как вообще можно судить о верности рещения задачи без условия?? Ни автор темы, ни ты, RathaR, при повторном ее (двукратном) поднятии так и не потрудились привести нормальное условие. Поэтому, все, что я писал - это просто пример "на тему". Я не писал задачу для тестов. И НЕ СТАЛ БЫ писать, пока не получил бы нормального условия.
Цитата
, но я, перед окончанием, ради интереса отправил оба решения: Lapp твоя прога на 12 тесте дала неверный результат))) Моя - на шестом
Я не буду даже смотреть в код. Это неуважение - взять учебный набросок (написанный по высосанному из пальца условию) и начать его тестировать.. Лень приводить условие - мне лень тебе отвечать..
Unconnected
3.11.2010 0:55
Цитата
Это неуважение - взять учебный набросок (написанный по высосанному из пальца условию) и начать его тестировать.. norespect.gif
Оой ну прям такое неуважение, набросок тестировать..
Lapp
3.11.2010 1:48
Цитата(Unconnected @ 3.11.2010 0:55)
Оой ну прям такое неуважение, набросок тестировать..
Ты сколотишь табурет, чтоб просто сидеть, а кто-то подаст его на конкурс кроватей. И потом терпи, когда будут показывать на тебя пальцами и говорить: а, это тот, чья кровать заняла последнее место на конкурсе..
Пока не будет точного условия, я в эту тему не отвечаю.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.