Персональная страничка
Диканева Тараса
Викторовича

Главная \ Преподавательское \ Программирование для начинающих

6. Задачи на перебор вариантов

Предыдущий раздел:

Следующий раздел:

Задание 6. Задачи на перебор вариантов

1. Для заданного целого числа проверьте, является ли оно кубом другого целого числа.

2. Задача Ал-Хорезми (ок. 780-850). Разложить число 10 на 2 слагаемых, сумма квадратов которых равна 58.

3. Задача Л.Эйлера. Некий чиновник купил лошадей и быков на сумму 1770 талеров. За каждую лошадь он уплатил по 31 талеру, а за каждого быка по 21 талеру. Сколько лошадей и быков купил чиновник? Используйте прием параметризации, чтобы легче было модифицировать программу при изменении рыночных цен и финансовых возможностей чиновника.

4. Теорема Ферма утверждает, что не существует решения в целых положительных числах уравнения x^n+y^n=z^n при n>2. Напишите программу, которая проверяла бы это утверждение при заданном n для всех x, y и z меньших 100.

5. Найдите все трехзначные числа, сумма цифр которых равна произведению цифр.

6. Решите следующие числовые ребусы:

    УДАР + УДАР = ДРАКА
    БУЛОК + БЫЛО = МНОГО
    КОКА + КОЛА = ВОДА
    ПОДАЙ — ВОДЫ = ПАША
    ТРИ + ТРИ + ТРИ = ДЫРА, причем (Ы + Ы) : Ы = Ы

Здесь каждая буква взаимнооднозначно соответствует какой-нибудь цифре. Первая цифра числа не может быть нулем.

Следующий раздел:

Предыдущий раздел:

33 комментария

  1. Ахметова Бакыт

    здравствуйте, в ребусе ТРИ + ТРИ + ТРИ = ДЫРКА, причем (Ы + Ы) : Ы = Ы допущена ошибка, ответ должен быть ДЫРА (601*3=1803)

  2. Ахметова Бакыт

    извините, 601*3=1803, должно быть 403*3=1209, тогда ы=2

  3. Taras

    Действительно. Спасибо, исправил.

  4. Игорёк

    program zd36;
    var a,d,c,m,i,x,y:integer;
    begin
    for x:=1 to 10 do
    for y:=1 to 10 do
    if (x*x+y*y=58) then
    writeln(x);
    writeln(y);
    end.
    2-я задача. Где тут ошибка, почему выводит нужные числа и ещё 10 после них, как убрать ?

  5. Taras

    Подобные ошибки хорошо искать с помощью отладки. Это упущение с моей стороны, что я нигде не написал о ней. В ближайшее время постараюсь исправить.

    В сущности, это простая штука: программу можно выполнять не целиком, а построчно. В результате можно следить за тем в каком порядке на самом деле выполняются команды (он запросто может отличаться от того, который ты сам хотел организовать), а также просматривать чему на самом деле равны переменные. Сопоставляя порядок выполнения операторов и изменение переменных со своими ожиданиями, можно заметить в какой момент все пошло не так и, соответственно, понять, где и в чем ошибка.

    Соответствующие команды:
    F8 — выполнить одну строку.
    Ctrl-F5 — добавление переменной или выражения в окно просмотра (можно будет следить как они меняются после выполнения каждой строки).
    F4 — выполнение программы до строки, в которой стоит курсор (чтобы разом выполнить много строк).
    Ctrl-F2 — завершение отладки.

  6. Игорёк

    writeln(x);
    writeln(y); до этих строк (x*x+y*y=58) имеет значение true, хм… Спасибо

  7. Игорёк

    program zd36;
    var b,a,d,c,m,i,x,y:integer;
    begin
    for x:=1 to 10 do
    if ((x*x)+((10-x)*(10-x))=58) then
    writeln(‘x=’,x,’. ‘);
    for y:=1 to 10 do
    if ((y*y)+((10-y)*(10-y))=58) then
    writeln(‘y=’,y,’. ‘)

    end.
    Пришёл к этому, по другому упростить, до выполнения условий не смог.

  8. Taras

    Два цикла здесь одинаковы (с точностью до замены x на y). Один можно спокойно убрать. Сама идея — годится, но надо доработать.

    Предыдущий вариант тоже был подходящим. Там только маленькая ошибка.

  9. kmrt

    5 задание как програмировать

  10. Аноним
    var i:integer;
    begin
        
    [Было правильное решение. Стер.
    Тарас]
    
    end.
  11. Taras

    Кстати, правильно )

  12. Dima

    в пятой задаче нет решения или я что то не так сделал?

    var
      a, b, c, d, x, y: integer;
    begin
      for a:=100 to 999 do
        begin
          b:=a div 100;
          c:=(a div 10) mod 10;
          d:=(a mod 10);
        end;
        x:=b+c+d;
        y:=b*c*d;
        if x=y then 
        write(b, c, d);  
    end.
  13. Taras

    Решение есть. Например, 123.
    Такую ошибку, как у тебя, хорошо искать в режиме отладки, когда по шагам программу выполняешь и смотришь, что получается.

  14. Dima

    нашел, у меня пишущий цикл не там стоял )

  15. Dima

    я только что понял что не понимаю как работает — mod, я думал что например 123 mod 10 будет 0.3 что является остатком от деления, но выходит 3…

  16. Taras

    123 = 12*10 + 3

    12 — целая часть от деления (123 div 10)
    3 — остаток (123 mod 10)

    В общем,
    x mod y = x − y*(x div y)
    Вычитаем из x целое число раз по y. Что останется — остаток, он же mod.

    А 0.3 — это дробная часть: x − y*trunc(x/y)

  17. оксана

    Здравствуйте,задание 6 про булок + было = много. У меня получилось так:
    var
    a, b, c, d, f, x, y, z, a1, b1, c1, d1: integer;
    begin

    x:=((x div 10000)*10000)+(((x div 1000) mod 10)*1000)+(((x div 100) mod 10)*100)+(((x div 10) mod 10)*10)+(x mod 10);
    a:=x div 10000;
    b:=(x div 1000) mod 10;
    c:=(x div 100) mod 10;
    d:=(x div 10) mod 10;
    f:=x mod 10;
    y:=(a*1000+((y div 100) mod 10)*100+c*10+d);
    a1:=((y div 100) mod 10);
    z:=((z div 10000)*10000) + (((z div 1000) mod 10)*1000) + d*100 + (((z div 10) mod 10)*10) + d;
    b1:=z div 10000;
    c1:=(z div 1000) mod 10;
    d1:=(z div 10) mod 10;

    for a:=1 to 9 do
    for b:=0 to 9 do
    for c:=0 to 9 do
    for d:=0 to 9 do
    for f:=0 to 9 do
    for a1:=0 to 9 do
    for b1:=1 to 9 do
    for c1:=0 to 9 do
    for d1:=0 to 9 do
    begin
    if (a*10000 + b*1000 + c*100 + d*10 + f)+ (a*1000 + a1*100 + c*10 + d)=(b1*10000) + (c1*1000) + d*100 + (d1*10) + d then
    begin
    if (ab) and (ac) and (ad) and (af) and (aa1) and (ab1) and (ac1) and (ad1) and (bc) and (bd) and (bf) and (ba1) and (bb1) and (bc1) and (bd1)and (cd) and (cf) and (ca1) and (cb1) and (cc1) and (cd1)and (df) and (da1) and (db1) and (dc1) and (dd1) and (fa1) and (fb1) and (fc1) and (fd1) and (a1b1) and (a1c1) and (a1d1) and (b1c1) and (b1d1) and (c1d1) then
    begin
    writeln(a,b,c,d,f,’ ‘,a,a1,c,d,’ ‘,b1,c1,d,d1,d,’ ‘);
    end;
    end;
    end;
    end.
    А можно сделать программу покороче? Если да, то как?

  18. оксана

    в условии if (ab) и т.д. не проставился знак «не равно».

  19. Taras

    Решение абсолютно правильное. Хотя и выглядит немного громоздко, но идейно оно же простое. Проверяющий взаимную однозначность if, конечно, страшен. С использованием массивов его можно было бы заменить циклом с простым if’ом внутри. Но массивы вводятся позже.

    Единственное, я бы убрал внутренние три цикла, вычисляя b1, c1, d1 как

      z = (a*10000 + b*1000 + c*100 + d*10 + f)+ (a*1000 + a1*100 + c*10 + d);
      b1:=z div 10000;
      c1:=(z div 1000) mod 10;
      d1:=(z div 10) mod 10;

    При желании можно заняться дальнейшим сокращением перебора. Из того, что последние цифры в БЫЛО и МНОГО совпадают следует, что К = 0, значит остальные не могут быть нулем и т.д. Но прелесть перебора как раз в том, что, если вариантов не много (тут их меньше миллиарда), можно не думать, а просто перебирать.

  20. оксана

    Спасибо за ответ. Решила заняться программированием «с нуля», просто мне это интересно. Ваш сайт понравился, поскольку я люблю простые доступные объяснения. Много задач различной сложности. Спасибо. Меня интересует надо ли всегда стремиться сокращать программу до минимума или пускай остается громоздкой главное, что правильно работает?

  21. Taras

    Минимальная программа, как правило, эффективнее, понятнее, в ней реже обнаруживаются ошибки и ее проще переделать, если условия задачи изменятся. Наконец, она просто красивее. На практике встречается такое явление как дедлайн, и он иногда не позволяет сделать программу идеальной. Однако в случае учебной задачи, забота о красоте и лаконичности — это всегда хорошо. В конце концов, это ведет к усовершенствованию твоего программистского мастерства.

  22. оксана

    вот так лучше будет?
    var
    b,u,l,o,k,i,m,n,g,bulokbilo,mnogo: integer;
    begin
    for b:=1 to 9 do
    for u:=1 to 9 do
    for l:=1 to 9 do
    for o:=1 to 9 do
    for i:=1 to 9 do
    for m:=1 to 9 do
    for n:=1 to 9 do
    for g:=1 to 9 do
    begin
    bulokbilo:=10*(1100*b+100*u+11*l+10*i+o)+k+o;
    mnogo:=10*(1000*m+100*n+10*o+g)+o;
    k:=0;
    if (bu) and (bl) and (bo) and (bi) and (bm) and (bn) and (bg) and (ul) and (uo) and (ui) and (um) and (un) and (ug)and (lo) and (li) and (lm) and (ln) and (lg) and (oi) and (om) and (on) and (og) and (im) and (in) and (ig) and (mn) and (mg) and (ng) then
    begin
    if bulokbilo=mnogo then
    begin
    writeln(b,u,l,o,k,’ ‘,b,i,l,o,’ ‘,m,n,o,g,o,’ ‘);
    end;
    end;
    end;
    end.

  23. Taras

    Да, хорошо.

    Я бы для большей красоты написал

    writeln(b,u,l,o,k,' + ',b,i,l,o,' = ',m,n,o,g,o);

    И еще

    k:=0;

    стоит уже после того, как k использовано. Здесь все переменные — так называемые глобальные. Они по умолчанию, до любого присваивания, равны 0, так что все работает правильно. Но лучше на это не полагаться и присваивание переставить.

  24. Аноним

    Задача №4
    В условии задачи №4 допущена ошибка, т. к. теорема Ферма верна, при натуральных x, y и z.
    Пример программы работающей для целых чисел:
    program teorema;
    var
    n, x, y, z, a, x1, y1, z1:integer;
    begin
    readln(n);
    if n<3 then
    writeln('n должно быть больше 2-ух и целым числом! Попробуйте снова!')
    else
    for x:= -100 to 100 do
    for y:= -100 to 100 do
    for z:= -100 to 100 do
    begin
    for a:= 2 to n do
    begin
    x1:=x*x;
    y1:=y*y;
    z1:=z*z;
    x1:=x1*x;
    y1:=y1*y;
    z1:=z1*z;
    end;
    if x1+y1=z1 then
    writeln('x= ', x, '; ', 'y= ', y, '; ', 'z= ', z);
    end;
    end.
    Можете проверить, что при n=3 программа выведет очень много примеров "опровержения теоремы Ферма"!

  25. Taras

    Да, спасибо. Добавил в условие требование положительности.

  26. Роман

    Подскажите пожалуйста, верно ли решение задачи 4 (теорема Ферма). Ну очень хочется получить ответ :)
    var
    i,z,x,y,n:integer;
    begin
    writeln(‘введите необходимую степень n ‘);
    readln(n);
    for z:=1 to 99 do
    for x:=1 to 99 do
    for y:=1 to 99 do
    if power(z,n)=power(x,n)+power(y,n) then
    begin
    writeln(z,’, ‘,y,’, ‘,x);
    end;
    end.
    Заранее спасибо.

  27. АленА

    Ответ 6:
    a) УДАР + УДАР = ДРАКА:
    8126 + 8126 = 16252;

    b) БУЛОК + БЫЛО = МНОГО
    38270 + 3527 = 41797
    38610 + 3561 = 42171
    38690 + 3269 = 41959
    39160 + 3516 = 42676
    39170 + 3617 = 42787
    47810 + 4381 = 52191
    48790 + 4179 = 52969
    49170 + 4617 = 53787
    57380 + 5438 = 62818
    58210 + 5921 = 64131
    58470 + 5247 = 63717
    64320 + 6932 = 71252
    65310 + 6831 = 72141
    65480 + 6348 = 71828
    65810 + 6381 = 72191
    65830 + 6483 = 72313
    68210 + 6921 = 75131
    68230 + 6123 = 74353
    68390 + 6539 = 74929
    69130 + 6213 = 75343
    69380 + 6438 = 75818
    69480 + 6348 = 75828
    74390 + 7539 = 81929
    74690 + 7269 = 81959
    76210 + 7921 = 84131
    76320 + 7932 = 84252
    76450 + 7145 = 83595
    79130 + 7213 = 86343
    79140 + 7314 = 86454
    79230 + 7123 = 86353
    83410 + 8741 = 92151
    83610 + 8561 = 92171
    83740 + 8674 = 92414
    84160 + 8516 = 92676
    84610 + 8561 = 93171
    85470 + 8247 = 93717
    86230 + 8123 = 94353
    86250 + 8325 = 94575
    86570 + 8157 = 94727
    87130 + 8213 = 95343;

    c) КОКА + КОЛА = ВОДА
    3930 + 3980 = 7910;

    d) ПОДАЙ — ВОДЫ = ПАША
    10652 — 9067 = 1585;

    e) ТРИ + ТРИ + ТРИ = ДЫРА, причем (Ы + Ы) : Ы = Ы
    403 + 403 + 403 = 1209, (2 + 2)/2 = 2

    Может ли кроме «б» в остальных вариантах быть лишь один ответ?

  28. АленА

    Роман, спасибо за функцию power(x,n) — первый раз у вас увидела. Так возводить в степень значительно проще :)

  29. Alex_Kot

    Нет ли других способов решения ?

    Program ZZ_6_6_2; {Б У Л О К}
    var {Б Ы Л О}
    B,U,L,I,O,K,M,N,G: integer; {=========}
    a,c,d,e,f,h: integer; {М Н О Г О}
    begin
    for a:=1 to 9 do
    for c:=0 to 9 do
    for d:=0 to 9 do
    for e:=0 to 9 do
    for f:=0 to 9 do
    for h:=0 to 9 do
    begin
    if ((((h+f) mod 10)=f) and (((((((h+f) div 10)+f+d) div 10)+d+e) mod 10)=f) and (((((((((((h+f) div 10)+f+d) div 10)+d+e) div 10)+c+a) div 10)+a) div 10)=0)) then
    begin
    B:=a;
    U:=c;
    L:=d;
    I:=e;
    O:=f;
    K:=h;
    G:=(((h+f) div 10)+f+d) mod 10;
    N:=(((((((h+f) div 10)+f+d) div 10)+d+e) div 10)+c+a) mod 10;
    M:=(((((((((h+f) div 10)+f+d) div 10)+d+e) div 10)+c+a) div 10)+a) mod 10;
    if ((BU) and (BL) and (BI) and (BO) and (BK) and (BM) and (BN) and (BG) and (UL) and (UI) and (UO) and (UK) and (UM) and (UN) and (UG) and (LI) and (LO) and (LK) and (LM) and (LN) and (LG) and (IO) and (IK) and (IM) and (IN) and (IG) and (OK) and (OM) and (ON) and (OG) and (KM) and (KN) and (KG) and (MN) and (MG) and (NG)) then
    begin
    writeln(‘ ‘, B,U,L,O,K);
    writeln(‘ ‘, B,I,L,O);
    writeln(‘ ‘, M,N,O,G,O);
    writeln;
    end;
    end;
    end;
    writeln(‘ FINISH’);
    end.

  30. Alex_Kot

    В программе выше: if (BU) and (BL) и т.д.

  31. Alex_Kot

    Спасибо! Посмотрел вариант Оксаны и комент Тараса.
    С учетом h=0 количество циклов сокращается до 5.

  32. Ирина

    Здравствуйте, помогите решить номер 6 КОКА+ КОЛА= ВОДА

  33. Лиза

    Помогите написать программу, которая будет переводить матрицу6*6 в обратную

Добавить комментарий