Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2005.10.30;
Скачать: [xml.tar.bz2];

Вниз

Пятничные задачки. Сogito ergo sum.   Найти похожие ветки 

 
MBo ©   (2005-10-07 08:14) [0]

1. На маленьком острове стоит прожектор, луч которого освещает
отрезок поверхности моря длиной 1 км. Прожектор вращается с периодом 1 мин.
При какой минимальной скорости катер может незаметно подплыть к острову?

2. Начальная скорость снаряда зенитной пушки V. Какую форму имеет зона безопасности для самолетов?

3. Вася Пупкин получил два предложения о работе.
Фирма "Рога и Копыта" предлагает ему 18000$ в год с увеличением каждый год
на 2000$, а ООО "ЗюЗюЗю" предлагает тот же стартап с увеличением каждые полгода
на 500$. Куда ему лучше податься?

4. У ювелира было много серебряных колечек. Толщина колечка в сечении 0.5 мм.
Он сделал две цепочки, одна длиной 326 мм, вторая 426 мм.
Сколько всего колечек было, если на длинную он израсходовал
на 40 колечек больше, чем на короткую?

5. Металлический стержень согнут посередине под прямым угом и подвешен
на шарнире за один из концов. Найти угол между верхним отрезком и вертикалью.

6. Два автомобиля отправились одновременно из A в B по одной дороге с разными,
но постоянными скоростями, выражающимися натур. числами. Разность скоростей -
простое число. Расстояние от А до В 100 км. Через 2 часа расстояние от А до медленного
автомобиля было впятеро больше расстояния от В до второго автомобиля.
Найти скорости.

7. Три точки  A,В,С находятся на прямом берегу последовательно на расстоянии 50 и 50 м друг от друга.
Одновременно из B к С поплыл Петя, а из A к B - Вася с Тузиком. Тузик догнал Петю,
повернул назад и вышел на берег в точке B одновременно с Васей, а Петя в тот же момент
вышел в точке С. Скорости постоянны. Сколько проплыл Тузик?

8. Дан указатель на начало односвязного списка. Написать функцию, которая обращает его
за линейное время с использованием О(1) памяти

9. Написать функцию, которая производит циклический сдвиг строки длиной N
на расстояние M влево за время O(N) с использованием O(1) памяти.
Пример: при N=9,M=3 строка abcdefghi превращается в defghiabc

10. Любопытная задача, уже когда-то задавалась McSimm-ом:
Введение: известна задача о ханойских башнях:
Имеется 3 стержня, на левый надето N дисков уменьшающегося размера.
Требуется переложить их на правый с соблюдением правила - на каждом
шаге перкладывается один диск, на больший диск можно класть только меньший.
Например, для 3-х дисков кратчайшая последовательность такова
(номера стержней, откуда и куда идет перекладывание через черточку):
1-3 1-2 3-2 1-3 2-1 2-3 1-3
Кто еще не сталкивался с исходной задачей, может попробовать силы в ее
самостоятельном решении.

Собственно основная задача:
Составить алгоритм решения задачи для ПРОИЗВОЛЬНОГО допустимого начального
расположения дисков.


 
КаПиБаРа ©   (2005-10-07 08:25) [1]

1. 1км/мин


 
MBo ©   (2005-10-07 08:48) [2]

>КаПиБаРа ©   (07.10.05 08:25) [1]
>1. 1км/мин

нет


 
КаПиБаРа ©   (2005-10-07 08:51) [3]

MBo ©   (07.10.05 8:48) [2]
Понял. Не дурак :)


 
palva ©   (2005-10-07 09:13) [4]

2. Когда-то решал эту задачу в плоском варианте. Безопасная зона - все, что выше параболоида вращения (перевернутого).


 
MBo ©   (2005-10-07 09:20) [5]

>palva ©   (07.10.05 09:13) [4]
Ну эта задача рассчитана на тех, кто не сталкивался с получением огибающей семейства траекторий. В первый раз это интересно бывает вывести.


 
palva ©   (2005-10-07 09:20) [6]

5. pi/4 - arctg(1/2)


 
Sergey_Masloff   (2005-10-07 09:28) [7]

5) 18.4 градуса примерно? Ну tg = 1/3


 
КаПиБаРа ©   (2005-10-07 09:29) [8]

palva ©   (07.10.05 9:20) [6]
arctg(1/3)=18,43 градуса я тоже получил. Только не хватило ума в общем виде формулу вывести.


 
MBo ©   (2005-10-07 09:31) [9]

>palva ©   (07.10.05 09:20) [6]
>5. pi/4 - arctg(1/2)
>Sergey_Masloff   (07.10.05 09:28) [7]
>5) 18.4 градуса примерно? Ну tg = 1/3

Да, верно. Разные записи, но результат одинаковый.
Решается через моменты сил или на пальцах - через положение центра тяжести на одной вертикали с шарниром.


 
Rentgen ©   (2005-10-07 09:31) [10]


> 3. Вася Пупкин получил два предложения о работе.
> Фирма "Рога и Копыта" предлагает ему 18000$ в год с увеличением
> каждый год
> на 2000$, а ООО "ЗюЗюЗю" предлагает тот же стартап с увеличением
> каждые полгода
> на 500$. Куда ему лучше податься?


Повышение зарплаты в Рогах будет всегда больше в два раза. А вот что ему выбрать, это надо смотреть.

P.S.
Или слишком легко или опечатка?


 
MBo ©   (2005-10-07 09:37) [11]

>Rentgen ©   (07.10.05 09:31) [10]
Нетрудно, но не очевидно. Так куда Васе слать резюме?


 
Dok_3D ©   (2005-10-07 09:39) [12]

2 Rentgen ©   (07.10.05 09:31) [10]
Или слишком легко или опечатка?

Ни то, ни другое.
Это твоя невнимательность  :)


 
SvetaK   (2005-10-07 09:45) [13]

3. Если Вася меняет работу каждый год ,то ему лучше податься в  ООО "ЗюЗюЗю"  .Tогда он там за первый год заработает на 500*6=3000$ больше.


 
svetaK   (2005-10-07 09:49) [14]

ПАРДОН ПОТОРОПИЛАСЬ Tогда он там за первый год заработает на 500$ больше.


 
Кабан   (2005-10-07 09:52) [15]

нигде вроде не сказано, что на 500 повышается зарплата в каждом месяце, или я чего то не понимаю :)


 
Кабан   (2005-10-07 09:53) [16]

я бы послал в рога и копыта


 
КаПиБаРа ©   (2005-10-07 09:54) [17]

3. Если ежемесячную зарплату увеличивают на 2000 и 500, то в ООО "ЗюЗюЗю"


 
syte_ser78 ©   (2005-10-07 10:03) [18]

Rentgen ©   (07.10.05 9:31) [10]
Думаю тут смысл не столько в том что год или полгода, а в том что в первом случае  - фирма во втором ООО
Я выбираю ООО (хоть что такое "фирма" не понятно).


 
MBo ©   (2005-10-07 10:03) [19]

>Если ежемесячную зарплату увеличивают на 2000 и 500
нет, годовую


 
MBo ©   (2005-10-07 10:05) [20]

>syte_ser78 ©   (07.10.05 10:03) [18]
нет, форма собственности не имеет значения, названия я от фонаря написал


 
Sergey_Masloff   (2005-10-07 10:05) [21]

8) с колес наверное можно почистить

unit LList;

interface
 uses Classes, SysUtils;

type
 PNode = ^TNode;
 TNode = record
   Data : Pointer;
   Next : PNode;
 end;

var
 List : PNode;

function ReverseList(AList : PNode): PNode;
procedure PrintList(AList : PNode; ATarget : TStrings);

implementation

function ReverseList(AList : PNode): PNode;
var
 pPrev, pCur, pNext : PNode;
begin
 if AList^.Next = nil then
   Result := AList
 else begin
   pPrev := AList;
   pCur  := AList^.Next;
   AList.Next := nil;
   while (pNext <> nil) do
   begin
     pNext := pCur^.Next;
     pCur^.Next := pPrev;
     pPrev := pCur;
     pCur := pNext;
   end;
   Result := pPrev;
 end;
end;

procedure PrintList(AList : PNode; ATarget : TStrings);
var
 Node : PNode;
begin
 if AList <> nil then
 begin
   Node := AList;
   while Node^.Next <> nil  do
   begin
     ATarget.Add(IntToStr(Integer(Node^.Data)));
     Node := Node^.Next;
   end;
   ATarget.Add(IntToStr(Integer(Node^.Data)));
 end;
end;

end.


 
Кабан   (2005-10-07 10:07) [22]

6. 42 и 40


 
Fishka   (2005-10-07 10:16) [23]

6. 8 пар решений
(40,42) (35,43) (30,44) (25,45) (20,46) (15,47) (10,48) (5,49)


 
VICTOR_   (2005-10-07 10:51) [24]

4.
300 колечек


 
VICTOR_   (2005-10-07 11:14) [25]

1.
Рискну предположить
2/PI = 0.64


 
MBo ©   (2005-10-07 11:32) [26]

>MBo ©   (07.10.05 10:03) [19]
>Если ежемесячную зарплату увеличивают на 2000 и 500
>нет, годовую

уточню формулировку для 3 задачи, как описано в книжке:
1 предлагает 18000 в год, и каждый последующий год годовое
содержание будет увеличиваться на 2000
2 предлагает 18000 в год, и каждый полгода повышение зарплаты на 500 долларов, таким образом, за второе полугодие получит 9500.

>Кабан   (07.10.05 10:07) [22]
>6. 42 и 40

Да

>Fishka   (07.10.05 10:16) [23]
разность - простое число должна быть

VICTOR_   (07.10.05 10:51) [24]
4.300 колече

Да


 
Кабан   (2005-10-07 11:41) [27]

2 MBo
тогда пойду, где не 500 увеличивают
задача сначала не совсем корректно сформулирована была


 
MBo ©   (2005-10-07 12:21) [28]

>Кабан   (07.10.05 11:41) [27]
>тогда пойду, где не 500 увеличивают
>задача сначала не совсем корректно сформулирована была

Да вот так уж она была дана в источнике.
Насчет: "таким образом, за второе полугодие получит 9500"  - этого в условии не было, но подразумевалось в объяснении.
Собственно, говоря, если совершенно корректно сформулировать условие - никакого подвоха не будет ;)
Ну ладно, неудачная эта задача получилась.


 
GuAV ©   (2005-10-07 12:59) [29]

8.
procedure RotateLeft(var S: string; Count: Integer);
var
 I, J, B, Len, Replaced: Integer;
 Ch: Char;
begin
 Len := Length(S);
 B := 0;
 Replaced := 0;
 repeat
   Inc(B);
   Ch := S[B];
   J := B;
   repeat
     I := J;
     J := ((I + Count - 1) mod Len) + 1;
     if (J <> B) then
       S[I] := S[J]
     else
       S[I] := Ch;
     Inc(Replaced);
   until J = B;
 until Replaced = Len;
end;

procedure TForm1.Button1Click(Sender: TObject);
var S: string; I: Integer;
begin
 S := Edit1.Text;
 I := StrToInt(Edit2.Text);
 RotateLeft(S, I);
 Edit3.Text := S;
end;


 
Труп Васи Доброго ©   (2005-10-07 13:07) [30]

Я не пойму чего думать? 2000 в год по любому больше чем 500 за полгода=1000в год.
Если не так - объясните, я работу сменю.


 
default ©   (2005-10-07 13:09) [31]

7. 50(1+sqrt(2))
8. тривиальность
9. классика!


 
MBo ©   (2005-10-07 13:11) [32]

VICTOR_   (07.10.05 11:14) [25]
1.Рискну предположить 2/PI = 0.64

нет

>Sergey_Masloff

Рабочий цикл - правильный, обвязка не вполне корректная (не иниц. PNext, проверка AList.Next на входе без проверки самого AList).

Если это подправить, получится что-то вроде:


function RevList(Head: PNode): PNode;
var
 Temp, RevHead: PNode;
begin
 RevHead := nil;
 while Head <> nil do begin
   Temp := Head.Next;
   Head.Next := RevHead;
   RevHead := Head;
   Head := Temp;
 end;
 Result := RevHead;
end;


 
MBo ©   (2005-10-07 13:19) [33]

default ©   (07.10.05 13:09) [31]
7. 50(1+sqrt(2))

Да.

8. тривиальность

Ой ли?
Уверен, что большая часть программистов напишет это за несколько минут?
Если ты учился на программистской специальности, то подобные вещи наверняка проходились/задавались. Практической пользы от манипулирования односвязными списками, конечно, мало, но мыслить алгоритмически это приучает в какой-то мере.

9. классика!
Чтобы это стало классикой, сначала ведь кто-то должен был придумать, верно? ;)


 
default ©   (2005-10-07 13:24) [34]

MBo ©   (07.10.05 13:19) [33]
по 8 честно сказать с первых секунд было видно решение...я не считаю это своей заслугой скорее заслугой задачи...
9. в "Жемчужинах программирования" это задача есть, она великолепна!


 
GuAV ©   (2005-10-07 13:29) [35]

GuAV ©   (07.10.05 12:59) [29]

> 8.

Точнее это было 9


 
REP ©   (2005-10-07 13:48) [36]

3.
ЗюЗюЗю
1 полугодие 1г  9000
2 полугодие 1г  9500
1 полугодие 2г 10000
2 полугодие 2г 10500
---------------------
                    39000

Рога
1 год 18000
2 год 20000
---------------
        38000


 
MBo ©   (2005-10-07 14:17) [37]

GuAV ©   (07.10.05 12:59) [29]
9.

Трудно воспринимается, но "упаковка" красивая.


 
default ©   (2005-10-07 14:30) [38]

MBo ©   (07.10.05 14:17) [37]
да, неплохо бы словами объяснил
примерно суть такая(буквы отфени взяты)
слева стоит то что ставится на своё место справа то что затирается
d    c
b    d
k    b
e    k
то есть то что встало на предыдущем шаге на своём место можно затирать(в исходной позиции) на следующем шаге другим элементов для установки его на новое место

кстати, у Вас в ответе какой алгоритм?


 
Прынц   (2005-10-07 15:03) [39]

парни расслдабтесь и идите пить пиво, сегодня ж тяпница!


 
default ©   (2005-10-07 15:14) [40]

GuAV ©   (07.10.05 12:59) [29]
по-моему нифига не линеен
расскажи алгоритм на словах


 
default ©   (2005-10-07 15:15) [41]

Прынц   (07.10.05 15:03) [39]
"Покой нам только снится"(c)


 
MBo ©   (2005-10-07 15:31) [42]

>default ©   (07.10.05 14:30) [38]
>MBo ©   (07.10.05 14:17) [37]
>да, неплохо бы словами объяснил

у GuAV примерно так, если не ошибаюсь:
Запоминаем очередной (n-й) элемент, смещаем по очереди n+Shift*i -ые (по модулю) элементы на Shift влево, пока не упремся в n-Shift.

>кстати, у Вас в ответе какой алгоритм?
Ну конкретного и единственного ответа здесь нет.


 
default ©   (2005-10-07 15:36) [43]

MBo ©   (07.10.05 15:31) [42]
так линейности вроде не получается?


 
GuAV ©   (2005-10-07 15:51) [44]


>GuAV ©   (07.10.05 12:59) [29]
> расскажи алгоритм на словах

Внутренний repeat:

Запоминаем первый элемент и заменяем его элементом  удалённым на shift от первого, его в свою очередь удалённым от него на shift и т.д., при нахождении индекса каждого элемента осуществляем wrap по длине строки с помощью mod; этот цикл прекращается когда доходим обратно до первого элемента, при этом для последнего берется ранее запомненое значение первого.

Внешний repeat:

Вышеописанный цикл пройдёт только элементы с индексами (N*НОД)+1, где N-целое число, НОД - наибольший общий делитель shift и length. Поэтому ведется учёт количества перемещенных символов Replaced, и если при завершении внутреннего Repeat цикла оно меньше длины, то внутренний цикл повторяется уже начиная со второго символа, затем третьего и т.д., пока не будут перемещены все символы.


 
GuAV ©   (2005-10-07 16:00) [45]

Линейность - это

> за время O(N)

, что означает число операций при удлинении строки в N раз увеличивается в N раз ?

Тогда это у меня соблюдается.


 
default ©   (2005-10-07 16:05) [46]

GuAV ©   (07.10.05 16:00) [45]
да, всё нормально
"Линейность - это

> за время O(N)

, что означает число операций при удлинении строки в N раз увеличивается в N раз ?
"
и это тоже, хотя настоящий смысл O(N) более общий


 
MBo ©   (2005-10-07 16:10) [47]

>default ©   (07.10.05 15:36) [43]
>так линейности вроде не получается?

получается.
Это, можно сказать, усовершенствованный с точки зрения памяти аналог простого алгоритма с потреблением памяти O(N), когда мы в доп. память записываем сдвигаемый кусок A (выбрав меньший), сдвигаем оставшийся B, копируем на своб. место А.


 
default ©   (2005-10-07 17:07) [48]

MBo ©   (07.10.05 16:10) [47]
самый лучший алгоритм который я знаю - это с обращением
пусть исходная строка ab, a-часть строки длиной сдвига, b-остаток
R-переставляет наоборот строку
тогда
R(R(a)R(b)) есть решение задачи


 
oldman ©   (2005-10-07 17:40) [49]


> 3. Вася Пупкин получил два предложения о работе.
> ..........
> Куда ему лучше податься?


Устроиться на об работы!!!

:)))


 
MBo ©   (2005-10-07 17:43) [50]

>default ©   (07.10.05 17:07) [48]
Да, я знаю. По моим тестам процедура с обращением строки раза в полтора-два быстрее, а уж про изящество и так понятно.


 
default ©   (2005-10-07 18:04) [51]

MBo ©   (07.10.05 17:43) [50]
да у GuAV мудрёно
тем более надо доказывать его корректность
типа нет зацикливаний до момента встречи с сохранённым элементом и некоторое другое...
ещё рекурсивная версия есть


 
GuAV ©   (2005-10-07 23:11) [52]

1.
unit avHanoi;

interface

uses SysUtils, Classes;

type
 TStick = 1..3;

 TOnMove = procedure(Sender: TObject; Src, Dest: TStick) of object;

 THanoiTowers = class(TObject)
 private
   FBlocks: array of TStick;
   FOnChange: TNotifyEvent;
   FOnMove: TOnMove;
   function GetIsBlockOnStick(Stick: TStick; Block: Integer): Boolean;
   procedure SetBlockCount(const Value: Integer);
   function GetBlockOnStick(Block: Integer): TStick;
   procedure SetBlockOnStick(Block: Integer; const Value: TStick);
   function GetBlockCount: Integer;
 protected
   procedure Changed;
   procedure Moved(Src, Dest: TStick);
 public
   property BlockCount: Integer read GetBlockCount write SetBlockCount;
   property IsBlockOnStick[Stick: TStick; Block: Integer]: Boolean read GetIsBlockOnStick;
   property BlockOnStick[Block: Integer]: TStick read GetBlockOnStick write SetBlockOnStick;
   procedure Move(Src, Dest: TStick);
   property OnChange: TNotifyEvent read FOnChange write FOnChange;
   property OnMove: TOnMove read FOnMove write FOnMove;
 end;

type
 THanoiSolver = class(TObject)
 private
   FTowers: THanoiTowers;
   procedure SetTowers(const Value: THanoiTowers);
   procedure GetBlockToStick(Block: Integer; Stick: TStick);
 public
   property Towers: THanoiTowers read FTowers write SetTowers;
   procedure Solve;
 end;

implementation

{ THanoiTowers }

function THanoiTowers.GetIsBlockOnStick(Stick: TStick; Block: Integer): Boolean;
begin
 Result := BlockOnStick[Block] = Stick;
end;

procedure THanoiTowers.SetBlockCount(const Value: Integer);
begin
 SetLength(FBlocks, Value);
 Changed;
end;

function THanoiTowers.GetBlockCount: Integer;
begin
 Result := Length(FBlocks);
end;

procedure THanoiTowers.Changed;
begin
 if Assigned(FOnChange) then
   FOnChange(Self);
end;

function THanoiTowers.GetBlockOnStick(Block: Integer): TStick;
begin
 Result := FBlocks[Block - 1] + 1;
end;

procedure THanoiTowers.SetBlockOnStick(Block: Integer; const Value: TStick);
begin
 FBlocks[Block - 1] := Value - 1;
end;

procedure THanoiTowers.Move(Src, Dest: TStick);
var I, J: Integer;
begin
 I := 1;
 while BlockOnStick[I] <> Src do
 begin
   Inc(I);
   if I > BlockCount then
     raise Exception.Create("Invalid move: stick is empty");
 end;
 for J := I downto 1 do
   if IsBlockOnStick[Dest, J] then
     raise Exception.Create("Invalid move: stick has a smaller (or this) block");
 BlockOnStick[I] := Dest;
 Moved(Src, Dest);
 Changed;
end;

procedure THanoiTowers.Moved(Src, Dest: TStick);
begin
 if Assigned(FOnMove) then
   FOnMove(Self, Src, Dest);
end;

function GetRemainingStick(S1, S2: TStick): TStick;
begin
 if (S1 <> 1) and (S2 <> 1) then
   Result := 1
 else if (S1 <> 2) and (S2 <> 2) then
   Result := 2
 else if (S1 <> 3) and (S2 <> 3) then
   Result := 3
 else
   raise Exception.Create("out of sticks");
end;

{ THanoiSolver }

procedure THanoiSolver.GetBlockToStick(Block: Integer; Stick: TStick);
var I: Integer; Src: TStick;
begin
 Src := FTowers.BlockOnStick[Block];
 if Stick = Src then
   Exit; // already there
 for I := Block - 1 downto 1 do
 begin
   GetBlockToStick(I, GetRemainingStick(Src, Stick));
 end;
 FTowers.Move(Src, Stick)
end;

procedure THanoiSolver.SetTowers(const Value: THanoiTowers);
begin
 FTowers := Value;
end;

procedure THanoiSolver.Solve;
var I: Integer;
begin
 for I := FTowers.BlockCount downto 1 do
   GetBlockToStick(I, 3);
end;

end.


 
GuAV ©   (2005-10-07 23:12) [53]

Форма тестового проекта
.pas
unit avHMain;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ExtCtrls, avHanoi;

type
 TForm1 = class(TForm)
   PaintBox1: TPaintBox;
   Panel1: TPanel;
   btnSetCount: TButton;
   Panel2: TPanel;
   Memo1: TMemo;
   Edit1: TEdit;
   Bevel1: TBevel;
   Edit2: TEdit;
   Edit3: TEdit;
   Label1: TLabel;
   btnPlay: TButton;
   Bevel2: TBevel;
   btnSolve: TButton;
   chkRecord: TCheckBox;
   Bevel3: TBevel;
   btnClr: TButton;
   Bevel4: TBevel;
   btnRandomize: TButton;
   procedure PaintBox1Paint(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure btnSetCountClick(Sender: TObject);
   procedure btnPlayClick(Sender: TObject);
   procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
     Shift: TShiftState; X, Y: Integer);
   procedure PaintBox1Click(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
   procedure btnClrClick(Sender: TObject);
   procedure chkRecordClick(Sender: TObject);
   procedure btnSolveClick(Sender: TObject);
   procedure btnRandomizeClick(Sender: TObject);
 private
   FHanoi: THanoiTowers;
   FClickedRow: TStick;
   FClickedBlock: Integer;
   { Private declarations }
 public
   property Hanoi: THanoiTowers read FHanoi;
   procedure TryMove;
   procedure HanoiMove(Sender: TObject; Src, Dest: TStick);
   procedure HanoiChange(Sender: TObject);
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.PaintBox1Paint(Sender: TObject);
var
 BlockHeight,
 BlockDeltaHalfWidth,
 BlockHalfWidth,
 BlockPos,
 StickPos,
 I: Integer;
 S: TStick;

begin
 with  Hanoi, PaintBox1, Canvas do
 begin
   BlockHeight := Height div BlockCount;
   BlockDeltaHalfWidth := (Width div 6) div BlockCount;
   with Brush do
   begin
     Color := clWindow;
   end;
   for S := Low(S) to High(S) do
   begin
     StickPos := MulDiv(Width, S * 2 - 1, 6);
     BlockPos := Height;
     for I := BlockCount downto 1 do
       if IsBlockOnStick[S, I] then
     begin
       BlockHalfWidth := BlockDeltaHalfWidth * (I + 0);
       Rectangle(
           StickPos - BlockHalfWidth,
           BlockPos - BlockHeight,
           StickPos + BlockHalfWidth,
           BlockPos
         );
       Dec(BlockPos, BlockHeight);
     end;
     MoveTo(StickPos, 0);
     LineTo(StickPos, PaintBox1.Height);
   end;
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 FHanoi := THanoiTowers.Create;
 Hanoi.OnChange := HanoiChange;
 Hanoi.BlockCount := 4;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 FHanoi.Free;
end;

procedure TForm1.btnSetCountClick(Sender: TObject);
begin
 Hanoi.BlockCount := StrToInt(Edit1.Text);
end;

procedure NextNum(var I, J: Integer; const S: string);
var Len: Integer;
begin
 J := 0;
 Len := Length(S);
 while I <= Len do
   if (S[I] in ["0".."9"]) then
     Break
   else
     Inc(I);
 while I + J <= Len do
   if not (S[I + J] in ["0".."9"]) then
     Break
   else
     Inc(J);
end;

procedure TForm1.btnPlayClick(Sender: TObject);
var
 S: string;
 I, J: Integer;
begin
 TryMove;
 S := Memo1.Text;
 I := 1;
 NextNum(I, J, S);
 Edit2.Text := Copy(S, I, J);
 I := I + J;
 NextNum(I, J, S);
 Edit3.Text := Copy(S, I, J);
 I := I + J;
 Memo1.Text := Copy(S, I, MaxInt);
end;

function MulDiv(Number, Numerator, Denominator: Integer): Integer;
begin
 Result := Number * Numerator div Denominator;
end;

procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
var
 I, ClickedCol: Integer;
begin
 with Hanoi do
 begin
   with PaintBox1 do
   begin
     FClickedRow := MulDiv(X, 3, Width) + 1;
     ClickedCol :=  MulDiv(Height - Y - 1, BlockCount, Height) + 1;
   end;
   FClickedBlock := 0;
   for I := BlockCount downto 1 do
     if IsBlockOnStick[FClickedRow, I] then
     begin
       Dec(ClickedCol);
       if ClickedCol = 0 then
       begin
         FClickedBlock := I;
         Break;
       end;
     end;
 end;
end;

procedure TForm1.PaintBox1Click(Sender: TObject);
begin
 if FClickedRow = 0 then Exit;
 if FClickedBlock <> 0 then
 begin
   Edit2.Text := IntToStr(FClickedRow);
 end
 else
 begin
   Edit3.Text := IntToStr(FClickedRow);
   TryMove;
 end;
end;

procedure TForm1.TryMove;
var I, J: Integer;
begin
 if TryStrToInt(Edit2.Text, I) then
   if TryStrToInt(Edit3.Text, J) then
     Hanoi.Move(I, J);
end;

procedure TForm1.HanoiChange(Sender: TObject);
begin
 PaintBox1.Invalidate;
end;

procedure TForm1.btnClrClick(Sender: TObject);
begin
 Memo1.Lines.Clear;
end;

procedure TForm1.HanoiMove(Sender: TObject; Src, Dest: TStick);
begin
 Memo1.Text := Memo1.Text + Format(" %d-%d", [Src, Dest]);
end;

procedure TForm1.chkRecordClick(Sender: TObject);
begin
 if chkRecord.Checked then
   Hanoi.OnMove := HanoiMove
 else
   Hanoi.OnMove := nil;
end;

procedure TForm1.btnSolveClick(Sender: TObject);
begin
 with THanoiSolver.Create do
 try
   Towers := Self.Hanoi;
   Solve;
 finally
   Free;
 end;
end;

procedure TForm1.btnRandomizeClick(Sender: TObject);
var I: Integer;
begin
 Hanoi.BlockCount := Random(4) + 3;
 for I := 1 to Hanoi.BlockCount do
   Hanoi.BlockOnStick[I] := Random(3) + 1;
end;

end.


 
GuAV ©   (2005-10-07 23:12) [54]

.dfm
object Form1: TForm1
 Left = 202
 Top = 107
 Width = 637
 Height = 353
 Caption = "Form1"
 Color = clBtnFace
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clWindowText
 Font.Height = -11
 Font.Name = "MS Sans Serif"
 Font.Style = []
 OldCreateOrder = False
 OnCreate = FormCreate
 OnDestroy = FormDestroy
 PixelsPerInch = 96
 TextHeight = 13
 object Panel1: TPanel
   Left = 0
   Top = 0
   Width = 629
   Height = 161
   Align = alTop
   BevelInner = bvRaised
   BevelOuter = bvLowered
   TabOrder = 0
   object Bevel1: TBevel
     Left = 2
     Top = 2
     Width = 103
     Height = 39
     Shape = bsRightLine
   end
   object Label1: TLabel
     Left = 144
     Top = 16
     Width = 9
     Height = 13
     Caption = "to"
   end
   object Bevel2: TBevel
     Left = 138
     Top = 2
     Width = 103
     Height = 39
     Shape = bsRightLine
   end
   object Bevel3: TBevel
     Left = 280
     Top = 2
     Width = 65
     Height = 39
     Shape = bsRightLine
   end
   object Bevel4: TBevel
     Left = 360
     Top = 2
     Width = 65
     Height = 39
     Shape = bsRightLine
   end
   object btnSetCount: TButton
     Left = 40
     Top = 8
     Width = 57
     Height = 25
     Caption = "set count"
     TabOrder = 0
     OnClick = btnSetCountClick
   end
   object Memo1: TMemo
     Left = 8
     Top = 40
     Width = 609
     Height = 113
     TabOrder = 1
   end
   object Edit1: TEdit
     Left = 8
     Top = 8
     Width = 25
     Height = 21
     TabOrder = 2
     Text = "3"
   end
   object Edit2: TEdit
     Left = 112
     Top = 8
     Width = 25
     Height = 21
     TabOrder = 3
   end
   object Edit3: TEdit
     Left = 160
     Top = 8
     Width = 25
     Height = 21
     TabOrder = 4
   end
   object btnPlay: TButton
     Left = 192
     Top = 8
     Width = 41
     Height = 25
     Caption = "play"
     TabOrder = 5
     OnClick = btnPlayClick
   end
   object btnSolve: TButton
     Left = 432
     Top = 8
     Width = 57
     Height = 25
     Caption = "Solve !"
     TabOrder = 6
     OnClick = btnSolveClick
   end
   object chkRecord: TCheckBox
     Left = 280
     Top = 16
     Width = 57
     Height = 17
     Caption = "Record"
     TabOrder = 7
     OnClick = chkRecordClick
   end
   object btnClr: TButton
     Left = 248
     Top = 8
     Width = 25
     Height = 25
     Caption = "Clr"
     TabOrder = 8
     OnClick = btnClrClick
   end
   object btnRandomize: TButton
     Left = 352
     Top = 8
     Width = 65
     Height = 25
     Caption = "Randomize"
     TabOrder = 9
     OnClick = btnRandomizeClick
   end
 end
 object Panel2: TPanel
   Left = 0
   Top = 161
   Width = 629
   Height = 165
   Align = alClient
   BevelInner = bvRaised
   BevelOuter = bvLowered
   TabOrder = 1
   object PaintBox1: TPaintBox
     Left = 2
     Top = 2
     Width = 625
     Height = 161
     Align = alClient
     OnClick = PaintBox1Click
     OnMouseDown = PaintBox1MouseDown
     OnPaint = PaintBox1Paint
   end
 end
end


 
GuAV ©   (2005-10-08 00:05) [55]

На словах:

Переместить все диски на правый стержень от наибольшего к наименьшему

Переместить диск на стержень - убедится, что он ещё не на целевом стержне; затем переместить все диски меньше этого на стержень, не являющийся ни целевым, ни исходным для перемещаемого диска, от большего к меньшему; после чего переложить диск на стержень.


 
SergP.   (2005-10-08 04:32) [56]


> 3. Вася Пупкин получил два предложения о работе.
> Фирма "Рога и Копыта" предлагает ему 18000$ в год с увеличением
> каждый год
> на 2000$, а ООО "ЗюЗюЗю" предлагает тот же стартап с увеличением
> каждые полгода
> на 500$. Куда ему лучше податься?


С увеличением на 500 каждые полгода чего?
Годовой зарплаты или полугодовой ?



Страницы: 1 2 вся ветка

Форум: "Потрепаться";
Текущий архив: 2005.10.30;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.65 MB
Время: 0.036 c
14-1128674492
shc
2005-10-07 12:41
2005.10.30
Компонент для архивации


10-1105988385
BAYES
2005-01-17 21:59
2005.10.30
Сохранение Word


2-1128368845
Pasha L
2005-10-03 23:47
2005.10.30
Пробелы в ком строке


6-1121239399
kot andrei
2005-07-13 11:23
2005.10.30
запрос пароля


2-1128843624
Proxytel
2005-10-09 11:40
2005.10.30
TStringGrid - поставить выделение





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский