Помощь - Поиск - Пользователи - Календарь
Полная версия: задача про натуральное число
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Sofo4ka
задуманно натуральное число х.известны три числа- остатки от деления этого числа 3,5,7 - i,j,k соответсвенно. найти Х
klem4
а что непонятного ?

X mod 3 = a
X mod 5 = b
X mod 7 = c


a, b, c - известны

Задача кстати решалась, можно поискать.
Гость
х=3l*i
x=5m*j
x=7t*k


потом типа 3l*i=5m*j

так объяснили
volvo
Sofo4ka, простым перебором чисел находишь те, что удовлетворяют заданным условиям. Этого тебе вполне хватит (все официальные решения с олимпиад этой задачи основывались именно на переборе - проблем ни у кого не возникло...)
Sofo4ka
а у мя возникла )
volvo
В чем именно?

Запустить цикл от 1 до 32767 (максимально возможное число для Integer), и для каждого числа проверять равенство остатков от его деления на 3, 5, 7 числам i, j, k соответственно?
klem4
Вот что я придумал :

uses crt;
var
  i, j, k: Integer;
  c1, c2, c3, a, b, c: Integer;
  find: boolean;

begin
  clrscr;

  write('i = '); readln(i);
  write('j = '); readln(j);
  write('k = '); readln(k);

  find := false;
  c1 := 0;

  while (c1 < maxint) and not(find) do begin
    a := c1 * 3 + i;
    c2 := 1;
    while (c2 < maxint) and not(find) do begin
      b := c2 * 5 + j;
      if b > a then break;
      c3 := 1;
      while (c3 < maxint) and not(find) do begin
        c := c3 * 7 + k;
        if (c > b) or (c > a) then break;
        find := ((a = b) and (a = c)); 
        inc(c3);
      end;
      inc(c2);
    end;
    inc(c1);
  end;


  if find then writeln(a)
   else writeln('No found !');

  readln;
end.


Вот только будет ли это быстрее обычного перебора unsure.gif
klem4
Невероятно smile.gif

  global := 0;
  t1 := GetTickCount;

  repeat
    while (c1 < maxint) and not(find) do begin
      a := c1 * 3 + i;
      c2 := 1;
      while (c2 < maxint) and not(find) do begin
        b := c2 * 5 + j;
        if b > a then break;
        c3 := 1;
        while (c3 < maxint) and not(find) do begin
          c := c3 * 7 + k;
          if (c > b) or (c > a) then break;
          find := ((a = b) and (a = c));
          inc(c3);
        end;
        inc(c2);
      end;
      inc(c1);
    end;

    inc(global);
  until global = 900000;

  writeln('Result = ',a);

  t2 := GetTickCount;
  writeln('Time1 = ', t2 - t1);

  global := 0;
  t1 := GetTickCount;

  repeat
    for p := 1 to maxint do
     if (p mod 3 = i) and (p mod 5 = j) and (p mod 7 = k) then break;
    inc(global);
  until global = 900000;

  t2 := GetTickCount;
  writeln('Time2 = ', t2 - t1);

  writeln('Result = ', p);
volvo
Цитата
Невероятно smile.gif

Потому, что некорректно smile.gif Ты же не инициализируешь Find и C1 заново при каждой итерации, следовательно, у тебя в первом случае показывается время одной итерации, а во втором - время ВСЕХ... Вот так - корректнее:

uses windows, crt;
var
  i, j, k: Integer;
  c1, c2, c3, a, b, c,
  p, global: Integer;
  find: boolean;

  T: dword;

begin
  clrscr;

  write('i = '); readln(i);
  write('j = '); readln(j);
  write('k = '); readln(k);

  T := gettickcount();


  global := 0;
  repeat
    find := false;
    c1 := 0;
    while (c1 < maxint) and not(find) do begin
      a := c1 * 3 + i;
      c2 := 1;
      while (c2 < maxint) and not(find) do begin
        b := c2 * 5 + j;
        if b > a then break;
        c3 := 1;
        while (c3 < maxint) and not(find) do begin
          c := c3 * 7 + k;
          if (c > b) or (c > a) then break;
          find := ((a = b) and (a = c));
          inc(c3);
        end;
        inc(c2);
      end;
      inc(c1);
    end;

    inc(global);
  until global = 900000;

  if find then writeln(a)
   else writeln('No found !');
  writeln('klem1:: Time = ', gettickcount() - T);


  T := GetTickCount();

  global := 0;

  repeat
    for p := 1 to maxint do
     if (p mod 3 = i) and (p mod 5 = j) and (p mod 7 = k) then break;

    inc(global);
  until (global = 900000);

  writeln('Result = ', p);
  writeln('klem2:: Time = ', gettickcount() - T);


  readln;
end.
klem4
LOL smile.gif))))

Спасибо smile.gif)))

Sofo4ka, используй простой перебор smile.gif

Michael_Rybak
Только перебирать надо не до 32767, а до 3*5*7.

Если a == b (mod 3), то (a-b) == 0 (mod 3)
Если a == b (mod 5), то (a-b) == 0 (mod 5)
Если a == b (mod 7), то (a-b) == 0 (mod 7)

А если (a-b) == 0 (mod 3, 5 и 7), то (a-b) == 0 mod (3 * 5 * 7).

Поэтому, найдя первый ответ X, надо выводить по очереди все числа вида X + 105 * K, и только их.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.