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

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

Вернуться   Форум программистов > Delphi программирование > Паскаль, Turbo Pascal, PascalABC.NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 28.11.2011, 15:19   #1
Rebelition
Пользователь
 
Аватар для Rebelition
 
Регистрация: 03.06.2011
Сообщений: 33
Сообщение Олимпиадное задание

Решал сегодня олимпиаду. Долго сидел над одним заданием, но так и не решил, но очень интересно.
Задача большая я постараюсь сократить. Дизайнер сделал шкаф с полочками для ключей и повесил его за один край (т.е. он висит как ромб). Нумерация ячеек идет слева направо и сверху вниз. Пришли рабочие и повесили его нормально квадратом.
Входные данные - вводиться число от 1 до 30. (Это число ячеек с одной стороны т.е. если возвести в квадрат, то получим кол-во ячеек).
Выходные данные - должны быть выставлены цифры с номерами ячеек.
(Пример - если ввели 2 то ответ "в первой строке 1 3 и на следующей строке 2 4". Если ввели 3 то ответ " первая строка 1 3 6, вторая 2 5 8, третья 4 7 9).
P. S. если не понятно, могу картинку нарисовать.
P.P.S. думаю тут решается двумерными массивами.
Rebelition вне форума Ответить с цитированием
Старый 28.11.2011, 17:35   #2
IT-man
АльTRUEи$т
Форумчанин
 
Аватар для IT-man
 
Регистрация: 19.03.2009
Сообщений: 784
По умолчанию

Цитата:
если не понятно, могу картинку нарисовать.
Рисуй картинку!
И свои попытки решения!
Цитата:
«Никто не войдет в Рай, имея хотя бы крупицу гордыни в своем сердце». «Аллах Красив и любит красоту. Гордыня означает отказ от истины и высокомерие»
IT-man вне форума Ответить с цитированием
Старый 29.11.2011, 06:33   #3
Rebelition
Пользователь
 
Аватар для Rebelition
 
Регистрация: 03.06.2011
Сообщений: 33
По умолчанию

Цитата:
Сообщение от IT-man Посмотреть сообщение
Рисуй картинку!
http://s017.radikal.ru/i436/1111/bb/7c6833a1cd31.jpg
Свои попытки я с психу поудалял. Да и смотреть там было нечего. Хотел через двумерный массив зайти, но там заранее константы выставляются, а тут пользователь сам задает таблицу.
Rebelition вне форума Ответить с цитированием
Старый 29.11.2011, 07:55   #4
Zer0
Форумчанин
 
Аватар для Zer0
 
Регистрация: 13.12.2007
Сообщений: 788
По умолчанию

так ведь тут все просто
первая строка всегда будет начинаться с 1 и содержать n чисел, каждое последующее число равно предыдущее+индекс текущего+номер строки-1, т.е.
1 строка: 1 (1+2)=3 (3+3)=6 (6+4)=10 и т.д.
Каждая последующая строка высчитывается по тому же алгоритму, но первое число высчитывается как (первое число пред. строки)+(номер текущей строки)-1, т.е.

1 строка: 1 3 6 ...
2 строка: (1+2-1)=2 (2+2+2-1)=5 (5+3+2-1)=9 ...
3 строка: (2+3-1)=4 ...
и так далее
Строк так же будет n

UPD: для элементов нижней половины ромба алгоритм немного другой, пояснять алгоритм не буду, это условие выделено жирным шрифтом в коде ниже

P.S. олимпиадные задачи они такие, оптимальное решение без логики не построишь)
благодарность - сюда (не забываем писать от кого)

Последний раз редактировалось Zer0; 29.11.2011 в 08:11.
Zer0 вне форума Ответить с цитированием
Старый 29.11.2011, 07:58   #5
Zer0
Форумчанин
 
Аватар для Zer0
 
Регистрация: 13.12.2007
Сообщений: 788
По умолчанию

Пример для паскаля

Код:
var n,row,ind,firstElem,curElem:integer;
begin
readln(n);
firstElem:=1;
for row:=1 to n do begin 
  firstElem:=firstElem+row-1;
  curElem:=firstElem;
  write(curElem,' ');
  for ind:=2 to n do begin
    if (n-(ind+row-1)>=0) then
      curElem:=curElem+ind+row-1
    else
      curElem:=curElem+2*(n+1)-(ind+row);
    write (curElem,' ');
  end;
  writeln;
end;
end.
благодарность - сюда (не забываем писать от кого)

Последний раз редактировалось Zer0; 29.11.2011 в 08:09.
Zer0 вне форума Ответить с цитированием
Старый 29.11.2011, 07:59   #6
Zer0
Форумчанин
 
Аватар для Zer0
 
Регистрация: 13.12.2007
Сообщений: 788
По умолчанию

Простите, немного неправильно, этот алгоритм применим только для верхней половины, сейчас немного подумаю и поправлю
благодарность - сюда (не забываем писать от кого)
Zer0 вне форума Ответить с цитированием
Старый 29.11.2011, 10:11   #7
TinMan
Форумчанин
 
Аватар для TinMan
 
Регистрация: 05.09.2011
Сообщений: 869
По умолчанию

Зер0 прав, тут все просто, и никаких двумерных массивов не надо. Но я бы сказал, тут все ЕЩЕ проще, и ничего считать в цикле не надо. А надо просто выводить (в двойном цикле, ессно) по формулам. А формулы выводятся из формул для суммы арифметической прогрессии.
Код:
var
  i,j,n: integer;

begin
  readln(n);
  for i:=1 to n do begin
    for j:=1 to n do
      if i+j<=n then
        write((i+j-1)*(i+j) div 2-j+1:4)
      else
        write(n*n-(2*n-i-j+1)*(2*n-i-j+2) div 2+(n-j+1):4);
    writeln
  end
end.
Предпочитаю на "ты".
TinMan вне форума Ответить с цитированием
Старый 29.11.2011, 11:27   #8
Rebelition
Пользователь
 
Аватар для Rebelition
 
Регистрация: 03.06.2011
Сообщений: 33
По умолчанию

Спасибо всем за ответы. Жаль сам до этого не додумался.
Rebelition вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Олимпиадное задание. ALex25153 Помощь студентам 4 25.11.2011 20:32
олимпиадное задание Ponkole Помощь студентам 8 15.02.2011 10:19
Олимпиадное программирование VovanZ Свободное общение 4 02.03.2010 13:43
Олимпиадное задание) AleX CODER Общие вопросы Delphi 12 02.12.2008 21:26