неділю, 30 грудня 2018 р.


Завдання IІ етапу Всеукраїнської учнівської олімпіади

з інформатики у 2018/2019 н.р.



Задача A. Простий калькулятор (100 балів)
Обмеження часу: 1 с
Обмеження пам'яті: 128 M
Простий калькулятор може обчислювати наступні вирази:
Num1 + Num2
Num1 - Num2
Num1 * Num2
Num1 / Num2
Де num1 і num2 цілі числа (не більші за 100000).
Знайдіть значення заданого виразу. Символи + - * / позначають відповідно операції додавання, віднімання, множення та ділення відповідно. Всі операції цілочисельні, тобто 5/3=1.
Вхідні дані. Рядок містить вираз який має обчислити простий калькулятор.
Вихідні дані. Виведіть результат виразу, який потрібно обчислити.
Приклади вхідних та вихідних даних
input.txt
output.txt
3 * 12
36
16 + 45
61

Вся складність задачі в тому, що при зчитуванні вхідних даних необхідно врахувати символьний тип змінної, яка вказує математичну операцію. Але при зчитуванні символьної змінної в Pascal, якщо числа і операція розділені пропусками, тосимвольній змінній присвоїться значення - пропуск. Для усунення цієї помилки, потрібно зчитувати не одну, а три символьні змінні. Середня змінна і буде відповідати операції, інакше, середовище буде видавати помилку про невідповідність типів. Тоді програма в Delphi матиме вигляд:

program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
 f,g:text;a,b,c:integer; d,e,l:char;
begin
  assign(f,'input.txt');
  assign(g,'output.txt');
  reset(f);
  rewrite(g);
  read(f,a,e,d,l,b);
  if d='+' then c:=a+b;
  if d='-' then c:=a-b;
  if d='*' then c:=a*b;
  if d='/' then c:=a div b;
   write(g,c);
  close(f);
  close(g)
end.

Якщо ж не здогадатися перевірити спостереження значень змінних, для усунення помилки, можна скористатися роботою з рядками.  Тоді програма в Delphi матиме такий вигляд:

program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
 f,g:text;a,b,c,i,k:integer; e,d:string;
begin
  assign(f,'input.txt');
  assign(g,'output.txt');
  reset(f);
  rewrite(g);
  read(f,d);
 i:=pos(' ',d);
  val(copy(d,1,i-1),a,k);
  val(copy(d,i+3,length(d)-i-2),b,k);
  e:=copy(d,i+1,1);
  if e='+' then c:=a+b;
  if e='-' then c:=a-b;
  if e='*' then c:=a*b;
  if e='/' then c:=a div b;
   write(g,c);
  close(f);
  close(g)
end.

Простіше, звичайно, це робиться на С++, так як тут зчитування змінних різного типу проходить так як звичайно. Отож, програма матиме вигляд:

#include <fstream>

using namespace std;

int main(int argc, char *argv[]) {int a,b,s;
ifstream f;
ofstream g;
f.open("input.txt");
g.open("output.txt");
char c;
f>>a>>c>>b;
if (c='+') s=a+b;
if (c='-')s=a-b;
if (c='*')s=a*b;
if (c='/')s=a / b;
g<<s ;
g.close();
f.close();
}

Задача B. Задача Фокус-покус (100 балів)
Обмеження часу: 1 с
Обмеження пам'яті: 256 M
Петрик П’яточкін загадав число від 1 до 109, а Вам повідомив три остачі, які утворилися при діленні загаданого числа на числа 971, 997, 1033. Зробіть фокус – швидко відгадайте число. Напишіть програму, що за даними остачами, знаходить загадане число.
Вхідні дані. Єдиний рядок містить три натуральних числа.
Вихідні дані. Єдиний рядок має містити одне натуральне число.
Приклад вхідних та вихідних даних
input.txt
output.txt
5 10 15
835049324

Програма в Delphi може матиме такий вигляд:
    program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
 f,g:text;a,b,c,i,j,k,d:longint;
 begin
  assign(f,'input.txt');
  assign(g,'output.txt');
  reset(f);
  rewrite(g);
  read(f,a,b,c);
  for i:=1 to 1000000000 do
  if (i mod 971=a)and(i mod 997=b)and(i mod 1033=c)then
  write(g,i);
  close(f);
  close(g)
end.

Якщо використати вкладені цикли, то програма в Delphi матиме такий вигляд:

program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
 f,g:text;a,b,c,i,j,k,d:longint;
 begin
  assign(f,'input.txt');
  assign(g,'output.txt');
  reset(f);
  rewrite(g);
  read(f,a,b,c);
  for i:=1 to 1000 do
  for j:=1 to 1000 do
  for k:=1 to 1000 do
if (i*971+a=j*997+b)and(i*971+a=k*1033+c)then d:=i*971+a;
   write(g,d);
  close(f);
  close(g)
end.

Задача С. Розфарбування таблиці множення (100 балів)
Ім’я вхідного файлу: іnput.txt
Ім’я вхідного файлу: output.txt
Обмеження часу: 1 с
Обмеження пам'яті: 16 M
Таблицею множення назвемо таблицю розміру n рядків на m стовпців, в якій на перетині i-го рядка і j-ого стовпця розміщене число i * j (рядки і стовпці нумеруються з одиниці).
В одній з математичних шкіл було вирішено провести педагогічний експеримент. Для того, щоб учням було простіше запам'ятовувати таблицю множення, деякі числа в ній будуть пофарбовані в червоний, деякі - в синій, а деякі - в зелений колір (решта чисел будуть чорними).
Процес фарбування чисел можна умовно розбити на чотири етапи. На першому етапі всі числа фарбуються в чорний колір. На другому - всі парні числа фарбуються в червоний колір, на третьому - всі числа, що діляться на 3, фарбуються в зелений колір, на четвертому - всі числа, що діляться на 5, фарбуються в синій колір.
Директор школи хоче знати, яку кількість картриджів для принтерів необхідно закупити для друку таблиць. Тому йому необхідна інформація про те, скільки чисел якого кольору буде в розфарбованій таким чином таблиці множення n на m. Напишіть програму, яка допоможе у підрахунку таких кількостей.
Вхідні дані. Рядок містить два натуральних числа n і m (1 ≤ n, m ≤ 1000).
Вихідні дані. У першому рядку виведіть кількість чисел, пофарбованих у червоний колір, в другій - у зелений, в третій - у синій, в четвертій - у чорний. Дотримуйтесь формату, наведеному в прикладах.
Приклади вхідних та вихідних даних
input.txt
output.txt
10 10
RED : 21
GREEN : 39
BLUE : 36
BLACK : 4
5 2
RED : 5
GREEN : 2
BLUE : 2
BLACK : 1

program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
 f,g:text;n,m,b,c,i,j,k,d:longint;a:array[1..1000,1..1000]of longint;
 begin
  assign(f,'input.txt');
  assign(g,'output.txt');
  reset(f);
  rewrite(g);
  read(f,n,m);
  b:=0;c:=0;d:=0;k:=0;
  for i:=1 to n do
  for j:=1 to m do begin
  a[i,j]:=i*j;
  if a[i,j] mod 5=0 then b:=b+1 else
  if a[i,j] mod 3=0 then c:=c+1 else
  if a[i,j] mod 2=0 then d:=d+1 else k:=k+1 end;
  writeln(g,'RED : ',d);
  writeln(g,'GREEN : ',c);
  writeln(g,'BLUE : ',b);
  writeln(g,'BLACK : ',k);
  close(f);
  close(g)
end.

Задача D. Ліфт (100 балів)
Ім’я вхідного файлу: іnput.txt
Ім’я вхідного файлу: output.txt
Обмеження часу: 1 с
Обмеження пам'яті: 64 M
Щоб підняти на N-й поверх M-поверхового будинку новий холодильник, Степан визвав бригаду вантажників. Оплата роботи вантажників відбувається таким чином: за підйом холодильника на один поверх необхідно заплатити 200 гривень, за спуск на один поверх – 100 гривень. За підйом та спуск ліфтом оплата не береться. Незважаючи на те, що в Степановому будинку є ліфт, йому, напевно, все ж таки доведеться заплатити вантажникам, тому що ліфт зупиняється тільки на кожному K-му поверсі, починаючи з першого (тобто на поверхах з номерами 1, K+1, 2K+1, 3K+1, …). Необхідно знайти, якої мінімальної суми грошей буде достатньо, щоб вантажники доставили холодильник з першого поверху на N-й.
Вхідні дані. У рядку записані три числа: M (2≤M≤100), N (2≤NM) и K (2≤KM-1), розділені пропусками.
Вихідні дані. Вивести єдине число – мінімальну вартість підйому холодильника.
Приклад вхідних та вихідних даних
input.txt
output.txt
20 7 4
200
20 7 2
0

program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils;
 label 1;
var
 f,g:text;n,m,b,c,i,k,d:integer;
 begin
  assign(f,'input.txt');
  assign(g,'output.txt');
  reset(f);
  rewrite(g);
  read(f,m,n,k);
   i:=(n-1) div k;
  if i*k+1=n then begin c:=0;goto 1 end;
   b:=(n-(i*k+1))*200;
   d:=((i+1)*k+1-n)*100;
   if d<b then c:=d else c:=b;
  1:writeln(g,c);
  close(f);
  close(g)
end.

Немає коментарів:

Дописати коментар