Вы находитесь на странице: 1из 6

Задача 1.

Сумма и произведение

Были загаданы два целых числа: a и b. Вам сообщили их сумму и произведение (но не
сообщили, что есть что).
Например, если известно, что сумма и произведение двух чисел равны 5 и 6, то возможны
два варианта: числа 1 и 5 (сумма 6, произведение 5), или числа 2 и 3 (сумма 5,
произведение 6).
Требуется написать программу, которая по заданным числа x и y найдет все пары чисел a
и b, такие что сумма чисел равна x, а произведение – y, либо наоборот: сумма равна y, а
произведение – x ( 109 ≤ x, y ≤ 109).

Пример решения 1 (неэффективное решение)

Program Problem1_1;
Var
x,y,i,j,z: LongInt;
Begin
Write('Введите 2 целых числа: ');
Read(x,y);
If Abs(x)>Abs(y)
then z:=abs(x)
else z:=abs(y);
For i:=-z to z do
For j:=i to z do
If ((i+j=x)and(i*j=y))or((i+j=y)and(i*j=x))
then Write(' ',i,',',j);
End.

Пример решения 2

Program Problem1_2;
Var
x,y: LongInt;
D,i1,i2: Real;
Begin
Write('Введите 2 целых числа: ');
Read(x,y);
If (x*x-4*y<0)and(y*y-4*x<0)
then
Write ('таких чисел нет')
else
begin
D:=x*x-4*y;
If D>=0
then
begin
i1:=(x+Sqrt(D))/2;
If i1-Int(i1)=0
then Write(Round(i1),',',x-Round(i1),' ');
end;
D:=y*y-4*x;
If D>=0
then
begin
i2:=(y+Sqrt(D))/2;
If i2-Int(i2)=0
then Write(Round(i2),',',y-Round(i2),' ');
end;
If (i1-Int(i1)<>0)and(i2-Int(i2)<>0)
then Write ('таких целых чисел нет');
end;
End.

Задача 2. Количество делителей

Будем называть количество делителей числа n его красотой. Например, красота числа 12
равна 6.
Требуется написать программу, которая по числу k (1 ≤ k ≤ 109) найдет число с
максимальной красотой, не превышающее k.

Вариант решения

Program Problem2;
Var
n,i,j,k,max,num: LongInt;
Begin
max:=0;
num:=1;
Write('Число k: '); Read(k);
For j:=1 to k do
begin
n:=0;
For i:=1 to j do
If (j MOD i)=0
then n:=n+1;
If n>max
then
begin
max:=n;
num:=j;
end;
end;
Write('Число: ',num,', кол-во делителей: ',max);
End.

Задача 3. Разбиения на слагаемые

Разбиения числа n на слагаемые – это набор целых положительных чисел, сумма которых
равна n. При этом разбиения, отличающиеся лишь порядком слагаемых, считаются
одинаковыми, поэтому можно считать, что слагаемые в разбиении упорядочены по
невозрастанию.
Например, существует 7 разбиений числа 5 на слагаемые:

5 = 1+1+1+1+1
5 = 2+1+1+1
5 = 2+2+1
5 = 3+1+1
5 = 3+2
5 = 4+1
5=5

В приведенном примере разбиения упорядочены лексикографически – сначала по первому


слагаемому в разбиении, затем по второму, и так далее.
Требуется написать программу, которая выведет в лексикографическом порядке все
разбиения на слагаемые заданного числа n (1 ≤ n ≤ 20).
Вариант решения

Program Problem3;
Type
arr = array [byte] of byte;
Var
N,i,j,L : byte;
X : arr;

Procedure Slag (var X:arr; var L:byte);


Var
i,j,s:byte;
Begin
i:=L-1;
s:=X[L];
While (i>1) and (X[i-1]<=X[i]) do
begin
s:=s+X[i];
dec(i)
end;
inc(X[i]);
L:=i+s-1;
For j:=i+1 to L do
X[j]:=1
End;

Begin
j:=1;
WriteLn('Введите натуральное число в диапазоне от 1 до 20');
Write ('N = ');
ReadLn(N);
If (N<1) or (N>20)
then N:=0;
L:=N;
For i:=1 to L do
X[i]:=1;
Write(N);
Write(' = ');
For i:=1 to L do
begin
Write(X[i]);
If i<>L
then Write(' + ')
end;
Writeln;
Repeat
Slag (X,L);
Write(N);
Write(' = ');
inc(j);
For i:=1 to L do
begin
Write(X[i]);
If i<>L
then Write(' + ')
end;
WriteLn
Until L=1;
WriteLn('Существует ',j,' разбиений числа ',N,' на слагаемые');
End.

Задача 4. Разбиения на пары

Задано 2n целых чисел. Требуется разбить их на пары, так, чтобы сумма произведений
чисел в парах была как можно больше.
Например, если заданы числа 1, 2, 3 и 4, то оптимальный способ разбиения на пары – (1,
2) и (3, 4). В этом случае искомая сумма равна 14.
Требуется написать программу, которая по заданному числу n (1 ≤ n ≤ 100) и набору из 2n
чисел выдаст их оптимальное разбиение на пары.
Вариант решения

Program Problem4;
Var
x,Sum,N: Integer;
A : Array[1..200] of Integer;
i,j : byte;
Begin
Write('Введите количество пар, не большее 100: '); Read(N);
Write('Введите исходный массив: '); For i:=1 to 2*N do Read(A[i]);
For i:=2 to 2*N do
For j:=2*N downto i do
If A[j-1]>A[j]
then
begin
x:=A[j-1];
A[j-1]:=A[j];
A[j]:=x;
end;
For i:=1 to 2*N do
Write(A[i],' ');
Sum:=0;
i:=1;
While i<2*N do
begin
Sum:=Sum+A[i]*A[i+1];
Inc(i,2);
end;
Write('Sum=',Sum);
End.

Задача 5. Палиндромы

Палиндромом называется строка, которая одинаково читается слева направо и справа


налево. Например, строка «шалаш» является палиндромом.
Задана строка. Удалим из нее все пробелы и найдем все подстроки результата, которые
являются палиндромами.
Например, для строки «мадам в шалаше» искомые подстроки: «м», «а», «д», «ада»,
«мадам», «в», «ш», «л», «ала», «шалаш», «е».
Требуется написать программу, которая читает строку длиной не более 1000 символов и
выводит все палиндромы, которые в ней встречаются. Палиндромы, которые встречаются
несколько раз, следует выводить лишь один раз.

Вариант решения

Program Problem5;
Var
A : Array[1..200] of String;
i,j,k : Integer;
S1,S2,S3: String;
c : Char;
Begin
WriteLn('Введите строку, ввод завершите клавишей Enter');
Read(S1);
S2:='';
For i:=1 to Length(S1) do
If S1[i]<>' ' then S2:=S2+S1[i];
WriteLn('***Строка без пробелов***'); WriteLn(S2);
{*** Подсчет всех палиндромов ***}
k:=1;
For i:=1 to Length(S2) do
begin
{*Если палиндром содержит нечетное количество символов (1,3,5...)*}
j:=0;
S3:='';
While (S2[i-j]=S2[i+j])AND(i-j>=1)AND(i+j<=Length(S2)) do
begin
If j<>0 then S3:=S2[i-j]+S3+S2[i+j] else S3:=S2[i];
A[k]:=S3;
k:=k+1;
j:=j+1;
end;
{*Если палиндром содержит 2 символа*}
If (S2[i]=S2[i+1])AND(i<Length(S2)) then
begin
S3:=S2[i]+S2[i+1];
A[k]:=S3;
k:=k+1;
end;
{*Если палиндром содержит четное количество символов (4,6...)*}
j:=0;
While (i<Length(S2))AND(S2[i]=S2[i+1])AND
(S2[i-j]=S2[i+1+j])AND(i-j>=1)AND
(i+1+j<=Length(S2)) do
begin
If j<>0 then S3:=S2[i-j]+S3+S2[i+1+j];
A[k]:=S3;
k:=k+1;
j:=j+1;
end;
end;
WriteLn('***Вывод всех палиндромов***');
For i:=1 to k do Write(A[i],' ');
{*** Вывод без повторов ***}
WriteLn;
WriteLn('***Вывод без повторов***');
For i:=1 to k-1 do
For j:=i+1 to k do
If A[i]=A[j] then A[j]:='';
For i:=1 to k do
If A[i]<>'' then Write(A[i],' ');
End.