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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 05.04.2011, 17:08   #1
Dj Troy
Пользователь
 
Регистрация: 05.04.2011
Сообщений: 16
По умолчанию Задача про рыбалку

Помогите решить задачу. Формулировка. Два друга собрались идти на рыбалку. Нужно написать чтобы программа высчитывала равное количество вещей. Например я ввожу 5 3 3 в ответе программы должно вывести у одного 5 у второго 3 3. Кто знает как е1 решить. У меня идейка есть но реализовать как её не знаю
Dj Troy вне форума Ответить с цитированием
Старый 05.04.2011, 17:11   #2
TOR
 
Регистрация: 02.02.2007
Сообщений: 9
По умолчанию

хм.5 <>3+3 или я что то не так понимаю?
TOR вне форума Ответить с цитированием
Старый 05.04.2011, 17:13   #3
Dj Troy
Пользователь
 
Регистрация: 05.04.2011
Сообщений: 16
По умолчанию

Я там правильно написал. Суть в том что есть у тебя три вещи вот такими массами 5 3 3. Ты несешь 5 кг друг 6 кг. Если тупо забить в цикл то программа выдаст такое что одному 5 3 а другому 3 но это уже неверно
Dj Troy вне форума Ответить с цитированием
Старый 05.04.2011, 17:14   #4
Dj Troy
Пользователь
 
Регистрация: 05.04.2011
Сообщений: 16
По умолчанию

Равное количесвто возможно и не получишь но чтобы получить максимально равное
Dj Troy вне форума Ответить с цитированием
Старый 05.04.2011, 18:07   #5
Dj Troy
Пользователь
 
Регистрация: 05.04.2011
Сообщений: 16
По умолчанию

Народ помогите решить пожалуйста
Dj Troy вне форума Ответить с цитированием
Старый 05.04.2011, 18:42   #6
unbanned
Форумчанин
 
Аватар для unbanned
 
Регистрация: 23.11.2010
Сообщений: 530
По умолчанию

т.е. разделить между друзьями вещи, чтобы максимально выровнять массу, которую придется нести рыбакам?
unbanned вне форума Ответить с цитированием
Старый 05.04.2011, 19:51   #7
val_nnm
Форумчанин
 
Регистрация: 18.10.2009
Сообщений: 185
По умолчанию

Вот вам решение
Код:
Const MaxCount = 30;
Type
  Weights = record
    W:array[0..(MaxCount-1)] of Real;
    Count:integer;
  end;

Procedure ClearWeights(var p:Weights);
Begin
  p.Count := 0;
End;

Procedure AddWeight(var p:Weights; Weight:Real);
Begin
  p.W[p.Count] := Weight;
  p.Count := p.Count+1;
End;

Function GetNumberOfVariants(const p:Weights):Longint;
var temp:longint;
Begin
  temp := 1;
  GetNumberOfVariants := temp shl p.Count;
End;

Procedure SplitByVariant(const input:Weights; var out1:Weights; var out2:Weights; variant:Longint);
var i:integer;
Begin
  ClearWeights(out1);
  ClearWeights(out2);
  For i := 0 to input.Count-1 do
  Begin
    if (((variant shr i) and 1)=1) then
      AddWeight(out1,input.W[i])
    else
      AddWeight(out2,input.W[i])    
  End;
End;

Procedure WritelnWeights(var p:Weights);
var i:integer;
Begin
  for i := 0 to p.Count-1 do
    Writeln(p.W[i]:5:0);
End;

function GetSumWeights(const p:Weights):real;
var s:real;
    i:integer;
Begin
  s := 0;
  for i := 0 to p.Count-1 do
    s := s+p.W[i];
  GetSumWeights := s;
End;

var V:real;
    Source:Weights;
    i:longint;
    NumVariants:Longint;
    BestVariant:Longint;
    BestVariantValue:real;
    
    w1,w2:Weights;
    Temp:real;
Begin
  Writeln('Веедите веса (0 для окончания ввода, -1 для оканчания ввода показа промежуточных значений)');
  Repeat
    Readln(V);
    if (V>0) then AddWeight(Source,V);
  until (V<=0) or (Source.Count>=MaxCount) ;
  WritelnWeights(Source);
  NumVariants := GetNumberOfVariants(Source);
  Writeln('количество вариантов =',NumVariants);


  SplitByVariant(Source,w1,w2,0);
  BestVariantValue := abs(GetSumWeights(w1)-GetSumWeights(w2));
  BestVariant := 0;

    if (V<=-1) then Begin
      Writeln('---------------------------');
      WritelnWeights(w1);
      writeln('---');
      WritelnWeights(w2);
      Writeln('Вариант ',0,'  Суммы ',GetSumWeights(w1):5:0,
              ' и ',GetSumWeights(w2):5:0,' разница между ними ',BestVariantValue:5:0);
    End;


  for i := 1 to NumVariants-1 do Begin

    SplitByVariant(Source,w1,w2,i);

    Temp := abs(GetSumWeights(w1)-GetSumWeights(w2));
    if (Temp<BestVariantValue) then Begin
      BestVariantValue := Temp;
      BestVariant := i;
    End;
    if (V<=-1) then Begin
      Writeln('---------------------------');
      WritelnWeights(w1);
      writeln('---');
      WritelnWeights(w2);
      Writeln('Вариант ',i,'  Суммы ',GetSumWeights(w1):5:0,' и ',GetSumWeights(w2):5:0,' разница между ними ',Temp:5:0);
    End;
  End;


  SplitByVariant(Source,w1,w2,BestVariant);
  writeln;
  writeln;
  Writeln('Лучший вариант №',BestVariant);
  Writeln('---------------------------');
  WritelnWeights(w1);
  writeln('---');
  WritelnWeights(w2);
  Writeln('Суммы ',GetSumWeights(w1):5:0,' и ',GetSumWeights(w2):5:0,' разница между ними ',BestVariantValue:5:0);
End.
Конечно не самый быстрый алгоритм. Да и даже этот алгоритм проверяет несколько лишних вариантов. (если нужна скорость то нужно применать чтото вроде алгоритма ветвей и границ.)

Но даже на написание этого алгоритма потратил много времени.
Да и такие однодневные акаунты часто забывают даже спасибо сказать.

НЕМНОГО ПОДУМАВ
можно заменить
Код:
 for i := 1 to NumVariants-1 do Begin
на
Код:
 for i := 1 to (NumVariants div 2)-1 do Begin
что уменьшит количество перебераемых вариантов в 2 раза. (потому как половина вариантов заркальное отображение уже перебранных. т.е. что мы давали первоому рыбаку теперь даём второму рыбаку)
На С# пишу лучше чем на русском.
"У меня правильнописание хромает. Оно хорошее, но почему-то хромает."

Последний раз редактировалось val_nnm; 05.04.2011 в 20:27.
val_nnm вне форума Ответить с цитированием
Старый 05.04.2011, 20:25   #8
Dj Troy
Пользователь
 
Регистрация: 05.04.2011
Сообщений: 16
По умолчанию

Спасибо большое
Dj Troy вне форума Ответить с цитированием
Старый 06.04.2011, 08:53   #9
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

кстати, очень качественный (и простой!) алгоритм предложил Smitt&Wesson
в этой теме:
Разделение предметов по весу


Добавлено
Только хочу предупредить - алгоритм очень простой,
но, именно поэтому, он моежт вернуть не лучший вариант.
Лучший можно получить - только полным перебором!
впрочем, об этом можно почитать на страницах упомянутой выше темы!

Последний раз редактировалось Serge_Bliznykov; 06.04.2011 в 09:31.
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Задача про множество vereney Паскаль, Turbo Pascal, PascalABC.NET 3 20.03.2011 21:09
Задача на Си про текст Chargos Помощь студентам 5 17.01.2011 01:07
ЗАДАЧА ПРО КИНОТЕАТР NatawaB Паскаль, Turbo Pascal, PascalABC.NET 3 10.01.2011 20:09
задача про муху DarkMage Общие вопросы C/C++ 1 14.09.2010 20:59
Задача про мост Sparky Помощь студентам 23 12.09.2010 19:51