• Добро пожаловать на компьютерный форум Tehnari.ru. Здесь разбираемся с проблемами ПК и ноутбуков: Windows, драйверы, «железо», сборка и апгрейд, софт и безопасность. Форум работает много лет, сейчас он переехал на новый движок, но старые темы и аккаунты мы постарались сохранить максимально аккуратно.

    Форум не связан с магазинами и сервисами – мы ничего не продаём и не даём «рекламу под видом совета». Отвечают обычные участники и модераторы, которые следят за порядком и качеством подсказок.

    Если вы у нас впервые, загляните на страницу о форуме и правила – там коротко описано, как задать вопрос так, чтобы быстро получить ответ. Чтобы создавать темы и писать сообщения, сначала зарегистрируйтесь, а затем войдите под своим логином.

    Не знаете, с чего начать? Создайте тему с описанием проблемы – подскажем и при необходимости перенесём её в подходящий раздел.
    Задать вопрос Новые сообщения Как правильно спросить
    Если пришли по старой ссылке со старого Tehnari.ru – вы на нужном месте, просто продолжайте обсуждение.

Олимпиадные задачки

  • Автор темы Автор темы Mr Kejik
  • Дата начала Дата начала

Mr Kejik

Ученик
Регистрация
1 Ноя 2015
Сообщения
11
Реакции
0
Баллы
0
Олимпиадные задачки

Привет всем, господа, можете подсказать - какими способами можно решить эти задачи?

Олимпиада уже завершена - свои варианты прилагаю.
:beseda:
 

Вложения

  • Олимпиада.rar
    Олимпиада.rar
    2.1 KB · Просмотры: 32
  • VYxc4S1Yak4.webp
    VYxc4S1Yak4.webp
    75.1 KB · Просмотры: 196
  • KbYEgnxbpr8.webp
    KbYEgnxbpr8.webp
    77.1 KB · Просмотры: 158
  • aAXdQmkpYk0.webp
    aAXdQmkpYk0.webp
    72.1 KB · Просмотры: 151
Способом перебора, однако :)))
 
Это он до Покрова будет перебирать циферки в стозначном числе. :)
 
Какой вопрос - такой ответ :)
 
Ну посмотрел, в принципе ничего особо сложного, что там внутри архива не смотрел :)

Для первой задачи я бы следующий алгоритм применил:
1. Берем старший разряд, если он меньше 9, то декремент от 9 до значения разряда + 1
2. Заменяем значение разряда на текущее и проверяем делится ли на 3 без остатка, если делится, прерываем цикл и показываем полученное число
3. Если не нашли решения , то переходим к следующему по старшинству разряду, и далее к пункту 2


Остальные лень решать, но в принципе все решаемы не очень сложными методами :)
 
А да, так как 100 разрядные числа проверить на деление на 3 в разрядной сетке даже длинного целого не реально, для проверки можно сложить все разряды числа и проверить эту сумму на деление на 3 ...
 
Не, ну можно впрячься и это всё прорешать, ничего особо сложного, только вот так ли уж надо? Работы много, времени потребуется куча... К тому же там оговорен Кумир либо Pascal/Delphi, а товарищ пытается штурмовать это дело на СИ.
 
Нуу...
Там штук 10 языков было, в том числе и С++, и Java, и PHP.
Первая - задача вообще однострочная (на С++)
Метод перебора применен только в 4-ой задаче

А вообще, я просто совета искал, может кто знает еще пути для решения
 
А вообще, если хотите, ради интереса можете попробовать сделать 4-ую задачу через деление именно самого числа для выяснения ответа, а не через деление суммы разрядов. У моего отца очень хорошо получилось написать такое, но на 1С :)
 
Олег, +100500!

Да все задачи вполне решаемые, сложность решения заложена только в самой формулировке задачи, специально путают.
 
А вообще, если хотите, ради интереса можете попробовать сделать 4-ую задачу
Ах Вы, змей-искусАтель! :)
Ну ладно, уж не знаю, через что, но у меня получилось так (Free Pascal) :
Код:
Var
 S,S1,Dig_S,Dig_S1:String;
 DR,Code,DD:Word;
 i,k,Dig:Byte;
 b:boolean;

Procedure DigitalRoot(Sd:String; var Sr:String; var D:Word);
var
 P:Word;
 L,j,m:Byte;
begin
 L:=Length(Sd);
 P:=0;
 for j:=1 to L do
  begin
   Val(Sd[j],m,Code);
   Inc(P,m);
  end;
 STR(P,Sr);
 D:=P;
 if P>=10 then DigitalRoot(Sr,Sr,D);
end;

Begin
 Writeln('Enter the number (up to 255 digits):');
 Readln(S);
 DigitalRoot(S,S1,DR);
 b:=false;
 i:=0;
 Repeat
  Inc(i);
  Val(S[i],Dig,Code);
  k:=10;
  repeat
   Dec(k);
   STR(DR+k,Dig_S);
   DigitalRoot(Dig_S,Dig_S1,DD);
  until ((Dig+k<10) and ((DD mod 3)=0)) or (k=1);
  if ((Dig+k<10) and ((DD mod 3)=0)) then
   begin
    b:=true;
    Dig:=Dig+k;
   end;
 Until b or (i=Length(S));
 if b then
  begin
   S1:='';
   for k:=1 to i-1 do
    S1:=S1+S[k];
   STR(Dig,Dig_S);
   S1:=S1+Dig_S;
   for k:=i+1 to Length(S) do
    S1:=S1+S[k];
  end
 else
  begin
   S1:='';
   for k:=1 to Length(S)-1 do
    S1:=S1+S[k];
   S1:=S1+'6';
  end;
 Writeln('Result:');
 Writeln(S1);
 Readln
End.
Программа "переваривает" числа длиной до 255 цифр.
На всякий случай: смысл последнего ветвления в том, чтобы обработать число, состоящее из одних девяток. В этом случае нужно последнюю девятку заменить шестёркой.
Применена рекурсивная процедура вычисления цифрового корня.
 
На всякий случай: смысл последнего ветвления в том, чтобы обработать число, состоящее из одних девяток. В этом случае нужно последнюю девятку заменить шестёркой.
В тестах программу проверяли на числа не только из одних девяток, но также и из одних восьмерок - там тоже нужно понизить последнюю циферку :)

Ваша программа через получение строки работает?
Просто я так и не дошел - какой тип целого числа может "выдержать" 100-значное неотрицательное число (нужно около 512 байт)
Погуглим... :elk:
 
Ах Вы, змей-искусАтель!
Ну ладно, уж не знаю, через что, но у меня получилось так
Спасибо большое за поддержку :)
Я тут занимаюсь еще изучением верстки сайтов - на свою страничку вставлю этот код - на память :)
 
В тестах программу проверяли на числа не только из одних девяток, но также и из одних восьмерок - там тоже нужно понизить последнюю циферку
Да... не учел.
Ваша программа через получение строки работает?
Конечно.
Просто я так и не дошел - какой тип целого числа может "выдержать" 100-значное неотрицательное число (нужно около 512 байт) Погуглим...
Сколь мне известно, такого типа в природе не существует. Например, некоторые виды (не все!) ЯП Паскаль-семейства поддерживают 20-значные числа (8 байт), но это всего лишь до 18446744073709551615. Так что мне кажется, что остаются только строки.
 
Исправил. Теперь и восьмерки отрабатывает:
Код:
Var
 S,S1,S2,Dig_S,Dig_S1:String;
 DR,Code,DD:Word;
 i,k,Dig:Byte;
 b:boolean;

Procedure DigitalRoot(Sd:String; var Sr:String; var D:Word);
var
 P:Word;
 L,j,m:Byte;
begin
 L:=Length(Sd);
 P:=0;
 for j:=1 to L do
  begin
   Val(Sd[j],m,Code);
   Inc(P,m);
  end;
 STR(P,Sr);
 D:=P;
 if P>=10 then DigitalRoot(Sr,Sr,D);
end;

Begin
 Writeln('Enter the number (up to 255 digits):');
 Readln(S);
 DigitalRoot(S,S1,DR);
 b:=false;
 i:=0;
 Repeat
  Inc(i);
  Val(S[i],Dig,Code);
  k:=10;
  repeat
   Dec(k);
   STR(DR+k,Dig_S);
   DigitalRoot(Dig_S,Dig_S1,DD);
  until ((Dig+k<10) and ((DD mod 3)=0)) or (k=1);
  if ((Dig+k<10) and ((DD mod 3)=0)) then
   begin
    b:=true;
    Dig:=Dig+k;
   end;
 Until b or (i=Length(S));
 if b then
  begin
   S1:='';
   for k:=1 to i-1 do
    S1:=S1+S[k];
   STR(Dig,Dig_S);
   S1:=S1+Dig_S;
   for k:=i+1 to Length(S) do
    S1:=S1+S[k];
  end
 else
  begin
   S1:='';
   for k:=1 to Length(S)-1 do
    S1:=S1+S[k];
   DigitalRoot(S1,S2,DR);
   Val(S[Length(S)],Dig,Code);
   repeat
    Dec(Dig);
   until ((DR+Dig) mod 3)=0;
   STR(Dig,Dig_S);
   S1:=S1+Dig_S;
  end;
 Writeln('Result:');
 Writeln(S1);
 Readln
End.
 
всего лишь до 18446744073709551615

Владимир Игоревич, я немножко баловался ассемблером )))
dt — резервирование памяти для данных размером 10 байт.
Директивой dt можно задавать следующие значения:
выражение или константу, принимающую значение из диапазона:
для МП i8086:
для чисел со знаком –32 768...+32 767;
для чисел без знака 0...65 535;
для МП i386 и выше:
для чисел со знаком –2 147 483 648...+2 147 483 647;
для чисел без знака 0...4 294 967 295;
относительное или адресное выражение, состоящее из 32 или менее бит (для i80386) или 16 или менее бит (для младших моделей);
адресное выражение, состоящее из 16-битового сегмента и 32-битового смещения;
константу со знаком из диапазона –279...279-1;
константу без знака из диапазона 0...280-1;
строку длиной до 10 байт, заключенную в кавычки;
упакованную десятичную константу в диапазоне 0...99 999 999 999 999 999 999.
Отсюда.
 
Вот мой С++ код, переписанный на Паскаль
Код:
var
	number : string;
	sum, ost, i, err, digit : integer;
	got : boolean;

Begin
	readln(number);
	for i := 1 to length(number) do begin
		Val(number[i], digit, err);
		sum := sum + digit;
	end;
	ost := 3 - (sum mod 3);
	got := false;
	for i := 1 to length(number) do begin
		Val(number[i], digit, err);
		if (digit <= 9-ost) and (not got) then begin
			got := true;
			digit := digit + ost;
			while digit <= 6 do digit := digit + 3;
			write(digit);
		end else begin
			if (i = length(number)) and (not got) then begin
				got := true;
				digit := digit - ost;
				write(digit);
			end else
				write(digit);
		end;
	end;
End.
 
Назад
Сверху