Книга программиста/Задачи на PascalABC.Net
К оглавлению | Назад | Вперёд
Все программы, код которых выложен здесь, являются работоспособными. На момент написания программ использовалась среда PascalABC.Net 3.0.
Простые задачи
правитьОбработка множеств
правитьПересечение множеств
правитьbegin
var A := new SortedSet<integer>(Range(5, 25));
var B := new SortedSet<integer>(Range(17, 34));
var C := new SortedSet<integer>(Range(1, 20));
A.IntersectWith(B);
A.IntersectWith(C);
Writeln(A);
end.
var
Multiplicity: set of integer;
begin
for var i := 1 to ReadlnInteger('Count:') do Include(Multiplicity, ReadlnInteger()); Writeln(Multiplicity); var Count := 0; foreach var c in Multiplicity do if c < 0 then Inc(Count); WritelnFormat('Количество отрицательных чисел равно {0}.', Count);
end. </syntaxhighlight>
begin
WritelnFormat('Количество отрицательных элементов равно {0}.', ReadArrInteger(ReadlnInteger('N:')).ToSortedSet().Where(x -> x < 0).Count());
end.
Сортировки
правитьСортировка пузырьком
правитьbegin
var N := ReadlnInteger('Размер массива:');
var A := ReadArrInteger(N);
var IsSwapped := false;
for var j := N - 1 downto 0 do
begin
IsSwapped := false;
for var i := 0 to j - 1 do
if A[i] < A[i + 1] then
begin
Swap(A[i], A[i + 1]);
IsSwapped := true;
end;
if IsSwapped = false then break;
end;
Writeln(A);
end.
Шейкерная сортировка
правитьОписание алгоритма |
---|
|
const
N = 4;
var
A: array [0..N - 1] of integer;
Left, Right: integer;
begin
for var i := 0 to N - 1 do A[i] := Random(100);
Left := 0;
Right := N - 1;
while Left < Right do
begin
for var i := Right downto Left + 1 do
if A[i - 1] > A[i] then Swap(A[i - 1], A[i]);
for var i := Left + 1 to Right - 1 do
if A[i] > A[i + 1] then Swap(A[i], A[i + 1]);
Dec(Right);
Inc(Left);
end;
Writeln(A);
end.
Смотрите также: реализация на Python.
Сортировка элементов, удовлетворяющих условию
правитьbegin
var A := Arr(1, 4, 6, 1, 9, 3);
var Indexes := new List<integer>();
for var i := 0 to A.Length - 1 do
if A[i] mod 3 = 0 then
Indexes.Add(i);
for var i := 0 to Indexes.Count - 1 do
for var j := i + 1 to Indexes.Count - 1 do
if A[Indexes[i]] > A[Indexes[j]] then
Swap(A[Indexes[i]], A[Indexes[j]]);
Writeln(A);
end.
Обработка массивов
правитьПолные квадраты
правитьconst
N = 5;
var
A: array [0..N - 1] of integer;
function IsSquare(x: integer): boolean;
begin
var y := 1;
while Sqr(y) < x do
Inc(y);
Result := Sqr(y) = x;
end;
begin
for var i := 0 to N - 1 do
Readln(A[i]);
for var i := 0 to N - 1 do
if IsSquare(A[i]) then Write(A[i]:5);
Writeln();
end.
Поменять местами максимальный и первый элементы
правитьconst
N = 10;
var
A: array [0..N - 1] of integer;
Max: integer := integer.MinValue;
MaxI: integer;
procedure Print();
begin
for var i := 0 to N - 1 do
Write(A[i]:5);
Writeln();
end;
begin
for var i := 0 to N - 1 do
begin
Readln(A[i]);
if A[i] > Max then
begin
Max := A[i];
MaxI := i;
end;
end;
Print();
Swap(A[0], A[MaxI]);
Print();
end.
const
N = 10;
var
A: array [0..N - 1] of integer;
MaxI: integer = -1;
procedure Print();
begin
for var i := 0 to N - 1 do
Write(A[i]:5);
Writeln();
end;
begin
for var i := 0 to N - 1 do
begin
Readln(A[i]);
if (MaxI = -1) or (A[i] > A[MaxI]) then MaxI := i;
end;
Print();
Swap(A[0], A[MaxI]);
Print();
end.
Вставить число перед нечётными элементами
правитьconst
N = 10;
type
IntArray = array of integer;
var
A: IntArray;
Count: integer;
procedure Print();
begin
for var i := 0 to A.Length - 1 do
Write(A[i]:5);
Writeln();
end;
begin
SetLength(A, N);
for var i := 0 to N - 1 do
begin
Readln(A[i]);
Inc(Count, A[i] mod 2);
end;
SetLength(A, N + Count);
Print();
var i := N - 1;
var j := N + Count - 1;
while i >= 0 do
begin
A[j] := A[i];
if A[i] mod 2 <> 0 then
begin
A[j - 1] := 400;
Dec(j);
end;
Dec(i);Dec(j);
end;
Print();
end.
Сдвиг элементов массива
правитьСдвинуть элементы массива, который состоит из 4-х элементов так, чтобы из: a b c d получилось b c d a.
const
N = 4;
var
A: array [0..N] of integer;
procedure Print(s: string);
begin
Writeln(s);
for var i := 0 to N - 1 do
Write(A[i]);
Writeln();
end;
begin
for var i := 0 to N - 1 do
Readln(A[i]);
Print('Изначальный массив:');
var C := A[0];
for var i := 0 to N - 2 do
A[i] := A[i + 1];
A[N - 1] := C;
Print('Измененный массив:');
end.
//Аналог через List<T>.
begin
var L := ReadArrInteger(4).Println().ToList();
L.Add(L[0]); L.RemoveAt(0);
L.Println();
end.
Массив с максимумом максимумов
правитьВывести массив с максимумом максимумов двух массивов.
begin
var A := Arr(Arr(1, 2, 10), Arr(4, 5, 6)).MaxBy(x -> x.Max());
Writeln(A);
WritelnFormat('Индекс максимального элемента {0} равен {1}.', A.Max(), A.IndexMax(0));
end.
Смотрите также: реализация на Python.
Слияние отсортированных массивов
правитьvar
C: array of integer;
i, j, k: integer;
begin
var A := Arr(1, 6, 7, 45, 100, 210);
var B := Arr(2, 8);
SetLength(C, A.Length + B.Length);
while (i < A.Length) or (j < B.Length) do
begin
if (j >= B.Length) or (i < A.Length) and (j < B.Length) and (A[i] < B[j]) then
begin
C[k] := A[i];
Inc(i);
end
else if (i >= A.Length) or (i < A.Length) and (j < B.Length) and (A[i] >= B[j]) then
begin
C[k] := B[j];
Inc(j);
end;
Inc(k);
end;
C.Println();
end.
Разделение отрицательных и положительных чисел с сохранением порядка
правитьПереместить все отрицательные числа в левую половину массива, остальные - в правую. Порядок следования отрицательных и неотрицательных чисел должен быть сохранен.
const
N = 10;
D = 10;
var
A: array [0..N - 1] of integer;
procedure Print();
begin
for var i := 0 to N - 1 do
Write(A[i]:4);
Writeln();
end;
begin
for var i := 0 to N - 1 do
A[i] := -D + Random(2 * D + 1);
Print();
for var i := 0 to N - 1 do
for var j := N - 2 downto i + 1 do
if (A[j] > 0) and (A[j + 1] < 0) then
Swap(A[j], A[j + 1]);
Print();
end.
Обработка матриц без условных операторов
правитьЗамена отрицательных элементов на неотрицательные
правитьconst
N = 5;
M = 5;
var
A: array [0..N - 1, 0..M - 1] of integer;
procedure Print(d: integer);
begin
for var i := 0 to N - 1 do
begin
for var j := 0 to M - 1 do
Write(A[i, j]:d);
Writeln();
end;
Writeln();
end;
begin
for var i := 0 to N - 1 do
for var j := 0 to M - 1 do
A[i, j] := -10 + Random(20);
Print(4);
for var i := 0 to N - 1 do
for var j := 0 to M - 1 do
A[i, j] := (1 - 2 * Ord(A[i, j] < 0)) * A[i, j];
Print(4);
end.
Удвоить положительные элементы
правитьconst
N = 5;
M = 5;
var
A: array [0..N - 1, 0..M - 1] of integer;
procedure Print(d: integer);
begin
for var i := 0 to N - 1 do
begin
for var j := 0 to M - 1 do
Write(A[i, j]:d);
Writeln();
end;
Writeln();
end;
begin
for var i := 0 to N - 1 do
for var j := 0 to M - 1 do
A[i, j] := -10 + Random(20);
Print(4);
for var i := 0 to N - 1 do
for var j := 0 to M - 1 do
A[i, j] := (1 + Ord(A[i, j] > 0)) * A[i, j];
Print(4);
end.
Исключение нечетных элементов
правитьconst
N = 5;
M = 5;
var
A: array [0..N - 1, 0..M - 1] of integer;
procedure Print(d: integer);
begin
for var i := 0 to N - 1 do
begin
for var j := 0 to M - 1 do
Write(A[i, j]:d);
Writeln();
end;
Writeln();
end;
begin
for var i := 0 to N - 1 do
for var j := 0 to M - 1 do
A[i, j] := -10 + Random(20);
Print(4);
for var i := 0 to N - 1 do
for var j := 0 to M - 1 do
A[i, j] := Ord(Abs(A[i, j]) mod 2 = 0) * A[i, j];
Print(4);
end.
Обнуление отрицательных чисел и удвоение положительных
правитьconst
N = 5;
var
A: array [0..N - 1] of integer;
procedure Print();
begin
for var i := 0 to N - 1 do
Write(A[i]:4);
Writeln();
end;
begin
for var i := 0 to N - 1 do
Readln(A[i]);
Print();
for var i := 0 to N - 1 do
A[i] := Ord(A[i] > 0) * 2 * A[i];
Print();
end.
Задачи К. Полякова
правитьОбработка массивов
правитьУдаление лишних пробелов в строках массива
правитьbegin
ReadArrString(3).Select(x -> x.ToWords().JoinIntoString(' ')).Println();
end.
Использование x.ToWords() не эквивалентно x.Split().
Смотрите также: реализация на Python.
Локальные минимумы
правитьДан массив, содержащий 2014 положительных целых чисел. Напишите на одном из языков программирования программу, которая находит в этом массиве количество локальных минимумов. Локальным минимумом называется элемент массива, который меньше всех своих соседей. Например, в массиве из 6 элементов, содержащем числа 4, 6, 12, 7, 3, 8, есть два локальных минимума: это элементы, равные 4 и 3. Программа должна вывести общее количество подходящих элементов, значения элементов выводить не нужно. Исходные данные объявлены так, как показано ниже. Запрещается использовать переменные, не описанные ниже, но разрешается не использовать часть из описанных.
const
N = 2014;
var
A: array [0..N - 1] of integer;
K: integer;
begin
for var i := 0 to N - 1 do
Readln(A[i]);
if A[0] < A[1] then Inc(K);
if A[N - 2] > A[N - 1] then Inc(K);
for var i := 1 to N - 2 do
if (A[i - 1] > A[i]) and (A[i] < A[i + 1]) then Inc(K);
Writeln(K);
end.
Смотрите также: реализация на Python.
Минимальный чётный и нечётный элементы
правитьДан массив, содержащий неотрицательные целые числа, не превышающие 10 000. Необходимо вывести:
- минимальный чётный элемент, если количество чётных элементов не больше, чем нечётных;
- минимальный нечётный элемент, если количество нечётных элементов меньше, чем чётных.
Например, для массива из шести элементов, равных соответственно 4, 6, 12, 17, 9, 8, ответом будет 9 – наименьшее нечётное число, поскольку нечётных чисел в этом массиве меньше.
const
N = 20;
var
A: array [0..N - 1] of integer;
C1, C2, Min1, Min2: integer;
begin
Min1 := integer.MaxValue;
Min2 := integer.MaxValue;
for var i := 0 to N - 1 do
begin
Readln(A[i]);
if A[i] mod 2 = 0 then
begin
Inc(C1);
if A[i] < Min1 then Min1 := A[i];
end
else
begin
Inc(C2);
if A[i] < Min2 then Min2 := A[i];
end;
end;
if C1 <= C2 then Writeln(Min1) else Writeln(Min2);
end.
//Аналог через готовые методы.
begin
Writeln(ReadArrInteger(ReadlnInteger('N:')).GroupBy(x -> x mod 2 = 0).Last().Min());
end.
Смотрите также: реализация на Python.
Задача о сумме элементов
правитьДан целочисленный массив из 2000 элементов. Если сумма всех элементов массива чётная, нужно вывести количество нечётных (по значению) элементов массива, если нечётная – количество чётных. Например, для массива из 6 элементов, равных соответственно 2, 6, 12, 17, 3, 8, ответом будет 2 – количество нечётных элементов, так как общая сумма всех элементов чётна.
const
N = 2000;
var
A: array [0..N - 1] of integer;
S: integer;
K1, K2: integer;
begin
for var i := 0 to N - 1 do
begin
Readln(A[i]);
Inc(S, A[i]);
if A[i] mod 2 = 0 then Inc(K1) else Inc(K2);
end;
if S mod 2 = 0 then Write(K2) else Write(K1);
end.
//Аналог через готовые методы.
begin
var A := ReadArrInteger(ReadlnInteger('N:'));
Writeln(A.Count(x -> x mod 2 <> A.Sum() mod 2))
end.
Смотрите также: реализация на Python.
Пары с элементом кратным 3
правитьДан целочисленный массив из 20 элементов. Элементы массива могут принимать целые значения от –10 000 до 10 000 включительно. Опишите на естественном языке или на одном из языков программирования алгоритм, позволяющий найти и вывести количество пар элементов массива, в которых хотя бы одно число делится на 3. В данной задаче под парой подразумевается два подряд идущих элемента массива.
const
N = 20;
var
A: array [0..N - 1] of integer;
K: integer;
begin
for var i := 0 to N - 1 do
Readln(A[i]);
for var i := 0 to N - 2 do
if (A[i] mod 3 = 0) or (A[i + 1] mod 3 = 0) then Inc(K);
Writeln(K);
end.
//Аналог через готовые методы.
begin
Writeln(ReadArrInteger(ReadlnInteger('N:')).Pairwise((x, y) -> Ord((x mod 3) * (y mod 3) = 0)).Sum());
end.
Смотрите также: реализация на Python.
Числа, оканчивающиеся на 5
правитьДан целочисленный массив из 40 элементов. Элементы массива могут принимать целые значения от 0 до 10000 включительно. Опишите на естественном языке или на одном из языков программирования алгоритм, позволяющий найти и вывести количество пар элементов массива, в которых десятичная запись хотя бы одного числа оканчивается на 5.
const
N = 40;
var
A: array [0..N - 1] of integer;
K: integer;
begin
for var i := 0 to N - 1 do
Readln(A[i]);
for var i := 0 to N - 1 do
for var j := i + 1 to N - 1 do
if (A[i] mod 10 = 5) or (A[j] mod 10 = 5) then Inc(K);
Writeln(K);
end.
Смотрите также: реализация на Python.
Обработка строк
правитьУдаление лишних пробелов
правитьvar
S, S2: string;
i: integer := 1;
begin
Readln(S);
while i <= Length(S) do
begin
if S.Chars[i] = ' ' then
begin
S2 += ' ';
Inc(i);
end;
while (i <= Length(S)) and (S.Chars[i] = ' ') do Inc(i);
while (i <= Length(S)) and (S.Chars[i] <> ' ') do
begin
S2 += S.Chars[i];
Inc(i);
end;
end;
S := S2;
Writeln(S);
end.
Задача о школах
правитьНа вход программе подаются сведения о номерах школ учащихся, участвовавших в олимпиаде. В первой строке сообщается количество учащихся N, каждая из следующих N строк имеет формат:
<Фамилия> <Инициалы> <номер школы>
где <Фамилия> – строка, состоящая не более чем из 20 символов, <Инициалы> – строка, состоящая из 4-х символов (буква, точка, буква, точка), <номер школы> – не более чем двузначный номер. <Фамилия> и <Инициалы>, а также <Инициалы> и <номер школы> разделены одним пробелом. Пример входной строки:
Иванов П.С. 57
Требуется написать как можно более эффективную программу (укажите используемую версию языка программирования, например, Borland Pascal 7.0), которая будет выводить на экран информацию, из какой школы было меньше всего участников (таких школ может быть несколько). При этом необходимо вывести информацию только по школам, пославшим хотя бы одного участника. Следует учитывать, что N >= 1000.
const
N = 4;
M = 99;
var
Schools: array [1..M] of integer;
Data: string;
Max, MaxI: integer;
begin
for var i := 0 to N - 1 do
begin
Readln(Data);
Inc(Schools[StrToInt(Data.ToWords()[2])]);
end;
Max := integer.MinValue;
for var i := 1 to M do
if Schools[i] > Max then
begin
Max := Schools[i];
MaxI := i;
end;
WritelnFormat('В школу с номером {0} пришло наибольшее количество учеников ({1}).', MaxI, Max);
end.
Худшие ученики
правитьВариант задачи 1
правитьНа вход программе подаются сведения о сдаче экзаменов учениками 9-х классов некоторой средней школы. В первой строке сообщается количество учеников N, которое не меньше 10, но не превосходит 100, каждая из следующих N строк имеет следующий формат:
<Фамилия> <Имя> <оценки>
, где <Фамилия> – строка, состоящая не более чем из 20 символов, <Имя> – строка, состоящая не более чем из 15 символов, <оценки> – через пробел три целых числа, соответствующие оценкам по пятибалльной системе. <Фамилия> и <Имя>, а также <Имя> и <оценки> разделены одним пробелом. Пример входной строки:
Иванов Петр 4 5 3
Требуется написать как можно более эффективную программу (укажите используемую версию языка программирования, например, Borland Pascal 7.0), которая будет выводить на экран фамилии и имена трех худших по среднему баллу учеников. Если среди остальных есть ученики, набравшие тот же средний балл, что и один из трех худших, то следует вывести и их фамилии и имена.
const
N = 6;
M = 3;
type
TStudent = class
public
Name, Surname: string;
Assessments: array [0..2] of integer;
constructor(n, sn: string; r1, r2, r3: integer);
begin
Name := n;
Surname := sn;
Assessments[0] := r1;Assessments[1] := r2;Assessments[2] := r3;
end;
function Sum() := Assessments[0] + Assessments[1] + Assessments[2];
end;
var
Students: array of TStudent;
Data: string;
j: integer;
begin
SetLength(Students, N);
for var i := 0 to N - 1 do
begin
Readln(Data);
var a := Data.ToWords();
Students[i] := new TStudent(a[0], a[1], StrToInt(a[2]), StrToInt(a[3]), StrToInt(a[4]));
end;
Students := Students.OrderBy(v -> v.Assessments.Sum()).ToArray();
var i := 0;
var Sum := Students[0].Sum();
while i < N do
begin
while (i < N) and (Students[i].Sum() = Sum) do
begin
WritelnFormat('Ученик {0} {1} {2}-ый по счету имеет баллы {3}.', Students[i].Name, Students[i].Surname, j + 1, Students[i].Sum());
Inc(i);
end;
if i < N then
begin
Inc(j);
Sum := Students[i].Sum();
end;
if j >= M then break;
end;
end.
Вариант задачи 2
правитьВывести имена трех худших учеников и среднее арифметическое их баллов.
begin
ReadArrString(20).Select(x -> x.ToWords()).OrderBy(x -> x.Skip(2).Sum(v -> StrToInt(v))).
Select(x -> Format('{0} {1} {2}', x[0], x[1], x.Skip(2).Average(v -> StrToFloat(v)))).Take(3).Println();
end.
Абитуриенты, не допущенные к сдаче экзаменов
правитьВ некотором вузе абитуриенты проходят предварительное тестирование, по результатам которого могут быть допущены к сдаче вступительных экзаменов в первом потоке. Тестирование проводится по двум предметам, по каждому предмету абитуриент может набрать от 0 до 100 баллов. При этом к сдаче экзаменов в первом потоке допускаются абитуриенты, набравшие по результатам тестирования не менее 30 баллов по каждому из двух предметов. На вход программы подаются сведения о результатах предварительного тестирования. Известно, что общее количество участников тестирования не превосходит 500. В первой строке вводится количество абитуриентов, принимавших участие в тестировании, N. Далее следуют N строк, имеющих следующий формат:
<Фамилия> <Имя> <Баллы>
Здесь <Фамилия> – строка, состоящая не более чем из 20 символов; <Имя> – строка, состоящая не более чем из 15 символов; <Баллы> – строка, содержащая два целых числа, разделенных пробелом, соответствующих баллам, полученным на тестировании по каждому из двух предметов. При этом <Фамилия> и <Имя>, <Имя> и <Баллы> разделены одним пробелом. Примеры входных строк:
Ветров Роман 68 59 Анисимова Екатерина 64 88
Напишите программу, которая будет выводить на экран фамилии и имена абитуриентов, потерпевших неудачу, то есть не допущенных к сдаче экзаменов в первом потоке. При этом фамилии должны выводиться в алфавитном порядке.
const
N = 3;
type
TPerson = auto class
Surname, Name: string;
Assessments: array of integer;
end;
var
A: array of TPerson;
begin
SetLength(A, N);
for var i := 0 to N - 1 do
begin
var p := ReadlnString().ToWords();
A[i] := new TPerson(p[0], p[1], p.Skip(2).Select(x -> StrToInt(x)).ToArray());
end;
Writeln('Не прошли экзамен:');
A.Where(x -> x.Assessments.Any(y -> y < 30)).OrderBy(x -> x.Name).
Select(x -> Format('{0} {1} {2}', x.Surname, x.Name, x.Assessments.JoinIntoString()) + NewLine).Println('');
end.
const
N = 3;
type
TPerson = record
Surname, Name: string;
Assessments: array of integer;
end;
var
A: array of TPerson;
begin
SetLength(A, N);
for var i := 0 to N - 1 do
begin
var p := ReadlnString().ToWords();
A[i].Surname := p[0];
A[i].Name := p[1];
A[i].Assessments := p.Skip(2).Select(x -> StrToInt(x)).ToArray();
end;
Writeln('Не прошли экзамен:');
A.Where(x -> x.Assessments.Any(y -> y < 30)).OrderBy(x -> x.Name).
Select(x -> Format('{0} {1} {2}', x.Surname, x.Name, x.Assessments.JoinIntoString()) + NewLine).Println('');
end.
Задача о сотрудниках
правитьНа вход программе подаются сведения о телефонах всех сотрудников некоторого учреждения. В первой строке сообщается количество сотрудников N, каждая из следующих N строк имеет следующий формат:
<Фамилия> <Инициалы> <телефон>
где <Фамилия> – строка, состоящая не более чем из 20 символов, <Инициалы> - строка, состоящая не более чем из 4-х символов (буква, точка, буква, точка), <телефон> – семизначный номер, 3-я и 4, я, а также 5-я и 6-я цифры которого разделены символом «–». <Фамилия> и <Инициалы>, а также <Инициалы> и <телефон> разделены одним пробелом. Пример входной строки:
Иванов П.С. 555-66-77
Сотрудники одного подразделения имеют один и тот же номер телефона. Номера телефонов в учреждении отличаются только двумя последними цифрами. Требуется написать как можно более эффективную программу, которая будет выводить на экран информацию, сколько в среднем сотрудников работает в одном подразделении данного учреждения.
const
N = 3;
var
A: array of string;
begin
SetLength(A, N);
for var i := 0 to N - 1 do
A[i] := ReadlnString().ToWords()[2];
Writeln(A.GroupBy(s -> s.ToWords()[2]).Println(NewLine).Average(g -> g.Count));
end.
Задача о сметанах
правитьВ молочных магазинах города Х продается сметана с жирностью 15, 20 и 25 процентов. В городе X был проведен мониторинг цен на сметану. Напишите эффективную по времени работы и по используемой памяти программу, которая будет определять для каждого вида сметаны, сколько магазинов продают ее дешевле всего. На вход программе сначала подается число магазинов N. В каждой из следующих N строк находится информация в следующем формате:
<Фирма> <Улица> <Жирность> <Цена>
где <Фирма> – строка, состоящая не более, чем из 20 символов без пробелов, <Улица> – строка, состоящая не более, чем из 20 символов без пробелов, <Жирность> – одно из чисел – 15, 20 или 25, <Цена> – целое число в диапазоне от 2000 до 5000, обозначающее стоимость одного литра сметаны в копейках. <Фирма> и <Улица>, <Улица> и <Жирность>, а также <Жирность> и <Цена> разделены ровно одним пробелом. Пример входной строки:
Перекресток Короленко 25 3200
Программа должна выводить через пробел 3 числа – количество магазинов, продающих дешевле всего сметану с жирностью 15, 20 и 25 процентов. Если какой-то вид сметаны нигде не продавался, то следует вывести 0. Пример выходных данных:
12 10 0
const
N = 5;
type
TData = auto class
MinPrice, Count: integer;
end;
var
FatContent: array [0..2] of TData;
begin
for var i := 0 to 2 do
FatContent[i] := new TData(integer.MaxValue, 0);
for var i := 0 to N - 1 do
begin
var p := ReadlnString().ToWords();
var j := (StrToInt(p[2]) - 15) div 5;
var price := StrToInt(p[3]);
if price < FatContent[j].MinPrice then
begin
FatContent[j].MinPrice := price;
FatContent[j].Count := 1;
end
else if price = FatContent[j].MinPrice then Inc(FatContent[j].Count);
end;
WritelnFormat('{0} {1} {2}', FatContent[0].Count, FatContent[1].Count, FatContent[2].Count);
end.
const
N = 5;
type
TData = record
MinPrice, Count: integer;
end;
var
FatContent: array [0..2] of TData;
begin
for var i := 0 to N - 1 do
begin
var p := ReadlnString().ToWords();
var j := (StrToInt(p[2]) - 15) div 5;
var price := StrToInt(p[3]);
if price < FatContent[j].MinPrice then
begin
FatContent[j].MinPrice := price;
FatContent[j].Count := 1;
end
else if price = FatContent[j].MinPrice then Inc(FatContent[j].Count);
end;
WritelnFormat('{0} {1} {2}', FatContent[0].Count, FatContent[1].Count, FatContent[2].Count);
end.
Задача о партиях
правитьИмеется список результатов голосования избирателей за несколько партий, в виде списка названий данных партий. На вход программе в первой строке подается количество избирателей в списке N. В каждой из последующих N строк записано название партии, за которую проголосовал данный избиратель, в виде текстовой строки. Длина строки не превосходит 50 символов, название может содержать буквы, цифры, пробелы и прочие символы. Пример входных данных:
6 Party one Party two Party three Party three Party two Party three
Программа должна вывести список всех партий, встречающихся в исходном списке, в порядке убывания количества голосов, отданных за эту партию. При этом название каждой партии должно быть выведено ровно один раз, вне зависимости от того, сколько голосов было отдано за данную партию. Пример выходных данных для приведенного выше примера входных данных:
Party three Party two Party one
var
D: Dictionary<string, integer>;
begin
D := new Dictionary<string, integer>();
for var i := 0 to ReadlnInteger('Количество избирателей:') - 1 do
begin
var p := ReadlnString();
if not D.ContainsKey(p) then D.Add(p, 1) else D[p] += 1;
end;
Writeln();
D.OrderByDescending(x -> x.Value).Select(x -> x.Key).JoinIntoString(NewLine).Println();
end.
//Аналог через готовые методы.
begin
ReadArrString(ReadlnInteger()).GroupBy(x -> x).OrderByDescending(x -> x.Count()).Select(x -> x.First()).JoinIntoString(NewLine).Println();
end.
Задача о цифрах
правитьНа вход программе подается последовательность символов, заканчивающаяся точкой. Требуется написать программу, которая определяет, есть ли в этой последовательности десятичные цифры, и выводит наибольшее число, которое можно составить из этих цифр. Ведущих нулей в числе быть не должно (за исключением числа 0, запись которого содержит ровно одну цифру). Если цифр нет, программа должна вывести на экран слово «Нет», а если есть – слово «Да» и в следующей строчке искомое число. Например, если исходная последовательность была такая:
Day 10, mice 8: "Year" 7 is a mistake 91.
то результат должен быть следующий:
Да 987110
begin
var A := ReadlnString().Where(x -> char.IsDigit(x));
Writeln(A.Count > 0 ? Format('{0}{1}{2}', 'Да', NewLine, A.OrderByDescending(x -> x).JoinIntoString('')) : 'Нет');
end.
Математические задачи
правитьЗадача о принадлежности точки кольцу
правитьvar
R1, R2, X, Y: real;
begin
Readln(R1, R2, X, Y);
if R1 > R2 then Swap(R1, R2);
var D := Sqrt(Sqr(X) + Sqr(Y));
if (D > R1) and (D < R2) then Writeln('Точка внутри кольца.') else Writeln('Точка вне кольца.');
end.
Смотрите также: реализация на Python.
Задача о решении уравнений
правитьvar
A, B, C, D, X1, X2: real;
begin
Readln(A, B, C);
D := Sqr(B) - 4 * A * C;
if D >= 0 then
begin
var d2 := Sqrt(D);
var a2 := 2 * A;
X1 := (-B + d2) / a2;
X2 := (-B - d2) / a2;
if X1 = X2 then
WritelnFormat('Найден один корень, равный {0}', X1)
else
WritelnFormat('Найдены два корня, равные {0} и {1}', X1, X2);
end
else
WritelnFormat('Ошибка нахождения корней: недопустимое значение {0} для D (< 0).', D);
end.
Смотрите также: реализация на Python.
Простое число с максимальным количеством единиц в двоичном представлении
правитьfunction F(a: integer): integer;
begin
while a <> 0 do
begin
if a mod 2 = 1 then Inc(Result);
a := a div 2;
end;
end;
begin
Writeln(ReadArrInteger(10).Where(x -> (x = 1) or (Range(2, Trunc(Sqrt(x))).All(y -> x mod y <> 0))).MaxBy(x -> F(x)));
end.
//Аналог через готовые методы.
begin
Writeln(ReadArrInteger(10).Where(x -> (x = 1) or (Range(2, Trunc(Sqrt(x))).All(y -> x mod y <> 0))).
MaxBy(x -> System.Convert.ToString(x, 2).Count(ch -> ch = '1')));
end.
Простое число
правитьfunction IsPrime(a: integer): boolean;
begin
Result := false;
if (a mod 2 = 0) and (a <> 2) then exit;
var i := 3;
while i <= Round(Sqrt(a)) do
if a mod i = 0 then
exit
else
Inc(i, 2);
Result := true;
end;
begin
var X := ReadlnInteger();
WritelnFormat('Число {0} {1}простое.', X, IsPrime(X) ? '' : 'не');
end.
Подсчёт числа инверсий
правитьbegin
var A := ArrRandom(10, 0, 10);
Writeln(A);
var Count := 0;
for var i := 0 to A.Length - 1 do
for var j := i + 1 to A.Length - 1 do
if A[j] > A[i] then
Inc(Count);
WritelnFormat('Количество инверсий равно {0}.', Count);
end.
Интегрирование
правитьtype
TFunction = function(x: real): real;
function Integrate(a, b: real; c: integer; func: TFunction): real;
begin
var s := (b - a) / c;
for var i := 0 to c - 1 do
Result += Abs(func(a + i * s));
Result *= s;
end;
begin
Writeln(Integrate(-1, 1, 100, Sin));
end.
Ханойские башни
правитьvar
N: integer;
procedure F(d, l1, l2: integer);
var
delta, dm: integer;
begin
delta := 6 - l1 - l2;
dm := d - 1;
if d <> 1 then F(dm, l1, delta);
WritelnFormat('Диск {0} переставлен на {1} на {2}.', d, l1, l2);
if d <> 1 then F(dm, delta, l2);
end;
begin
Readln(N);
F(N, 1, 3);
end.
Повышенная сложность
правитьЗадачи на алгоритмы
правитьЗадачи на обработку последовательностей
правитьЧисла, удовлетворяющие условию
правитьПодсчитать количество чисел, принадлежащих промежутку [A, B] и сумму чисел, стоящих на местах, кратных 3.
begin
var A := ReadlnInteger('A:');
var B := ReadlnInteger('B:');
var i := 0;
var Sum := 0;
var Count := 0;
var N := 0;
while i < B - A + 1 do
begin
Readln(N);
if (N >= A) and (N <= B) then Inc(Count);
if i mod 3 = 0 then Inc(Sum, N);
Inc(i);
end;
WritelnFormat('Количество чисел в [A, B] равно {0}. Сумма чисел равна {1}.', Count, Sum);
end.
begin
var A := ReadArrInteger(ReadlnInteger('N:'));
var R := Range(ReadlnInteger('A:'), ReadlnInteger('B:'));
WritelnFormat('Количество чисел, принадлежащих промежутку [{0}, {1}] равно {2}. ' + NewLine
+ 'Сумма чисел, стоящих на местах, кратных 3, равна {3}.',
R.First(), R.Last(), A.Count(x -> x in R), A.Where((x, i)-> i mod 2 = 0).Sum());
end.
Последовательность максимальной длины
правитьВариант с файлом
правитьconst
Path1 = 'C:\Ilya\AlgoРитмы\Файл1.txt';
Path2 = 'C:\Ilya\AlgoРитмы\Файл2.txt';
var
F1, F2: Text;
L: List<integer>;
N: integer;
MaxL: integer;
begin
Assign(F1, Path1);
Assign(F2, Path2);
Reset(F1);
Rewrite(F2);
L := new List<integer>();
while not Eof(F1) do
begin
Readln(F1, N);
L.Add(N);
end;
var i := 0;
N := L[0];
while i < L.Count do
begin
var len := 1;
while (i < L.Count) and (L[i] = N) do
begin
Inc(len);
Inc(i);
end;
if len > MaxL then
MaxL := len;
if i < L.Count then
N := L[i];
end;
Write(F2, MaxL);
Close(F1);
Close(F2);
end.
Вариант без файла
правитьbegin
Writeln(ReadlnString().AdjacentGroup().MaxBy(x -> x.Count()).First());
end.
Задача с CyberForum
править- Заполнить массив по формуле: 5.5 * Sin(index * H) + Cos(A * X + index * H), где H, A и X - числа, которые ввел пользователь.
- Удалить из массива все положительные элементы, которые удовлетворяют условию: A[index] < index / 3.
- Найти среднее арифметическое элементов, стоящих между первым минимальным по модулю и последним отрицательным элементами.
const
N = 10;
var
A: array [1..N] of real;
Exists: array [1..N] of boolean;
NegativeI: integer;
begin
var H := ReadlnInteger();
var X := ReadlnInteger();
var A := ReadlnInteger();
for var i := 1 to N do
begin
var c := i * H;
A[i] := 5.5 * Sin(c) + Cos(A * X + c);
Exists[i] := true;
end;
for var i := 1 to N do
if (A[i] > 0) and (A[i] < i / 3) then
Exists[i] := false;
var Min := real.MaxValue;
var MinI := 0;
for var i := 1 to N do
if Exists[i] and (Abs(A[i]) < Min) then
begin
Min := Abs(A[i]);
MinI := i;
end;
for NegativeI := N downto 1 do
if Exists[NegativeI] and (A[NegativeI] < 0) then
break;
var Sum := 0.0;
var Count := 0;
for var i := MinI to NegativeI do
if Exists[i] then
begin
Sum += A[i];
Inc(Count);
end;
WritelnFormat('Среднее арифметическое равно {0}.', Sum / Count);
end.
Определить является ли данная последовательность арифметической прогрессией
правитьbegin
var A := ReadlnInteger();
var B := ReadlnInteger();
var D := B - A;
var Yes := true;
while Yes and (B <> 0) do
begin
Swap(A, B);
B := ReadlnInteger();
if (B <> 0) and (B - A <> D) then
Yes := false;
end;
if Yes then Writeln('Yes') else Writeln('No');
end.
//Аналог через готовые методы.
const
Eps = 1E-5;
begin
var A := ReadlnString().ToReals().Incremental((x, y) -> y - x);
WritelnFormat('Последовательность - {0}арифметическая прогрессия.', A.All(x -> Abs(x - A.First()) < Eps) ? '' : 'не ');
end.
Сжатие последовательности
правитьВариант первый
правитьИз последовательности 1, 1, 3, 3, 5, 1 получить:
1:2 3:2 5:1 1:1
const
N = 6;
var
A: array [0..N - 1] of integer;
begin
for var i := 0 to N - 1 do
Readln(A[i]);
var K := A[0];
var Count := 0;
var i := 0;
while i < N do
begin
while (i < N) and (A[i] = K) do
begin
Inc(i);
Inc(Count);
end;
WritelnFormat('{0}:{1}', K, Count);
if i < N then
begin
K := A[i];
Count := 0;
end;
end;
end.
Вариант второй
править//Аналог через готовые методы.
begin
ReadlnString().AdjacentGroup().Select(x -> Format('{0}({1})', x.First, x.Count)).JoinIntoString('').Println();
end.
Удаление двух максимумов и двух минимумов
правитьbegin
var A := Arr(1, 2, 34, 4, 15, 6, 71, 8, 9);
A := A.Numerate().Println().OrderBy(x -> x[1]).Skip(2).SkipLast(2).OrderBy(x -> x[0]).Select(x -> x[1]).ToArray();
Writeln(A);
end.
Случайные последовательности
правитьПоследовательность без повторений
правитьconst
D = 5;
begin
for var i := 1 to 10 do
begin
var m := i * D;
Writeln(Random(m, m + D - 1));
end;
end.
Обработка чисел
правитьПеревод секунд в часы, минуты и секунды
правитьbegin
var Seconds := ReadlnInteger();
var H := Seconds div 3600 mod 24;
var M := Seconds mod 3600 div 60;
var S := Seconds mod 60;
WritelnFormat('{0}:{1}:{2}', H, M, S);
end.
Вывод делителей числа
правитьbegin
var X := ReadInteger('Введите целое число x (x > 1): ');
Assert(X > 1);
var I := 2;
WriteFormat('{0} = 1', X);
repeat
if X mod I = 0 then
begin
WriteFormat(' * {0}', I);
X := X div I;
end
else
I += 1;
until X = 1;
Writeln();
end.
Вывод цифр числа в правильном порядке
правитьvar
N: integer;
C: integer;
begin
Readln(N);
var N2 := N;
while N2 <> 0 do
begin
Inc(C);
N2 := N2 div 10;
end;
Dec(C);
C := Round(Power(10, C));
while C > 0 do
begin
Writeln(N div C);
N := N mod C;
C := C div 10;
end;
end.
Переворот числа
правитьvar
N: integer;
C: integer;
begin
Readln(N);
var N2 := N;
while N2 <> 0 do
begin
Inc(C);
N2 := N2 div 10;
end;
Dec(C);
C := Round(Power(10, C));
N2 := 0;
while N > 0 do
begin
N2 += N mod 10 * C;
N := N div 10;
C := C div 10;
end;
Writeln(N2);
end.
Квадраты чисел
правитьНайти все такие числа, запись которых совпадает с последними цифрами их квадрата.
function IsSuitable(a: integer): boolean;
begin
var b := Sqr(a);
Result := true;
while Result and (a <> 0) do
begin
if a mod 10 <> b mod 10 then Result := false;
a := a div 10;
b := b div 10;
end;
end;
begin
var N:=ReadlnInteger();
for var i := 1 to N do
if IsSuitable(i) then Writeln(i);
end.
Поиск натурального N
правитьВычислить такое N, при котором последовательность вида Sqrt(6 + Sqrt(6 + Sqrt(6 + ... Sqrt(6)))) / N приближается к 3 с погрешностью 10^(-4).
const
Infelicity = 1E-4;
begin
var F := Sqrt(6.0);
var N := 1;
while Abs(F - 3) > Infelicity do
begin
F := Sqrt(6 + F);
Inc(N);
end;
WritelnFormat('N = {0}.', N);
end.
Поиск наибольшего общего делителя
правитьДля пары чисел
правитьbegin
var A := ReadlnInteger('A:');
var B := ReadlnInteger('B:');
while (A <> 0) and (B <> 0) do
if A > B then A := A mod B else B := B mod A;
Writeln(A + B);
end.
Для N чисел
правитьconst
N = 4;
var
A: array[0..N - 1] of integer;
Outcome: integer;
function F(a, b: integer): integer;
begin
while (a <> 0) and (b <> 0) do
if a > b then a := a mod b else b := b mod a;
Result := a + b;
end;
begin
for var i := 0 to N - 1 do
Readln(A[i]);
Outcome := F(A[0], A[1]);
for var i := 2 to N - 1 do
Outcome := F(Outcome, A[i]);
WritelnFormat('НОД = {0}.', Outcome);
end.
Таблица умножения в шестнадцатеричной системе счисления
правитьconst
S = '0123456789ABCDEF';
function ToHex(x: integer): string;
begin
while x <> 0 do
begin
Result := S.Chars[x mod 16 + 1] + Result;
x := x div 16;
end;
end;
begin
for var i := 1 to 9 do
begin
for var j := 1 to 9 do
Write(ToHex(i * j):5);
Writeln();
end;
end.
Поразрядное сравнение чисел
правитьbegin
var A := ReadlnInteger('A:');
var B := ReadlnInteger('B:');
var C := 0;
while (A <> 0) and (B <> 0) do
begin
if A mod 10 = B mod 10 then Inc(C);
A := A div 10;
B := B div 10;
end;
WritelnFormat('Количество совпадений в равносильных разрядах чисел равно {0}.', C);
end.
Задачи на матрицы
правитьОбнуление элементов, стоящих выше главной диагонали и ниже побочной
правитьbegin
var N := ReadlnInteger();
var A := MatrRandom(N, N, 1, 10);
A.Println();
for var i := 0 to N - 1 do
for var j := 0 to N - 1 do
if (i < j) and (N - i - 1 < j) then
A[i, j] := 0;
Writeln();
A.Println();
end.
Треугольник Паскаля
правитьconst
M = 15;
var
A: array[1..M, 1..M] of integer;
N: integer;
begin
Write('Количество итераций: ');
Readln(N);
A[1, 1] := 1;
for var i := 2 to N + 1 do
for var j := 1 to N + 1 do
if (j = 1) or (j = i) then
A[i, j] := 1
else
A[i, j] := A[i - 1, j - 1] + A[i - 1, j];
for var i := 1 to N do
begin
for var j := 1 to N do
if A[i, j] <> 0 then write(A[i, j]:5);
Writeln();
end;
end.
Перемножение матриц
правитьvar
MatrixA, MatrixB: array [,] of integer;
procedure PrintMatrix(matrix: array [,] of integer);
begin
for var i := 0 to Length(matrix, 0) - 1 do
begin
for var j := 0 to Length(matrix, 1) - 1 do
Write(matrix[i, j]:4);
Writeln();
end;
end;
function MultMatrixes(matrixA, matrixB: array [,] of integer): array [,] of integer;
begin
if Length(matrixA, 1) = Length(matrixB, 0) then
begin
SetLength(Result, Length(matrixA, 0), Length(matrixB, 1));
for var i := 0 to Length(Result, 0) - 1 do
for var j := 0 to Length(Result, 1) - 1 do
for var AjBi := 0 to Length(matrixA, 1) - 1 do
Result[i, j] += matrixA[i, AjBi] * matrixB[AjBi, j];
end
else
raise new Exception('Количество столбцов первой матрицы не равно количеству строк второй.');
end;
begin
SetLength(MatrixA, 3, 2);
SetLength(MatrixB, 2, 2);
for var i := 0 to Length(MatrixA, 0) - 1 do
for var j := 0 to Length(MatrixA, 1) - 1 do
MatrixA[i, j] := Random(6);
for var i := 0 to Length(MatrixB, 0) - 1 do
for var j := 0 to Length(MatrixB, 1) - 1 do
MatrixB[i, j] := Random(6);
Writeln('MatrixA:');
PrintMatrix(MatrixA);
Writeln();
Writeln('MatrixB:');
PrintMatrix(MatrixB);
Writeln();
Writeln('MatrixC:');
PrintMatrix(MultMatrixes(MatrixA, MatrixB));
end.
Сортировки
правитьБыстрая сортировка
правитьОписание алгоритма |
---|
|
const
N = 10;
var
A: array of integer;
procedure Sort(var x: array of integer; l, r: integer);
var
i, j, m: integer;
begin
i := l;
j := r;
m := x[(l + r) div 2];
while i <= j do
begin
while x[i] < m do Inc(i);
while x[j] > m do Dec(j);
if i <= j then
begin
Swap(x[i], x[j]);
Inc(i);
Dec(j);
end;
end;
if l < j then Sort(x, l, j);
if i < r then Sort(x, i, r);
end;
begin
SetLength(A, N);
for var i := 0 to N - 1 do A[i] := Random(100);
Writeln(A);
Sort(A, 0, N - 1);
Writeln(A);
end.
- Элементы x[i], x[j] рано или поздно найдутся: поскольку даже если все элементы стоят на своих местах, то x[i] и x[j] будут равны m.
- Если i пробежал n элементов и указывает на n + 1, то все n элементов стоят на правильных местах. Аналогично и с j.
Бинарный поиск
правитьconst
N = 10;
var
A: array of integer;
procedure Sort(var x: array of integer; l, r: integer);
var
i, j, m: integer;
begin
i := l;
j := r;
m := x[round((l + r) / 2)];
repeat
while x[i] < m do Inc(i);
while x[j] > m do Dec(j);
if i <= j then
begin
Swap(x[i], x[j]);
Inc(i);
Dec(j);
end;
until i > j;
if l < j then Sort(x, l, j);
if i < r then Sort(x, i, r);
end;
procedure BinarySeach(var a: array of integer; x, l, r: integer);
function NewMiddle() := round((l + r) / 2);
begin
var m := NewMiddle();
while l <= r do
begin
if a[m] = x then
begin
WritelnFormat('Элемент {0} был найден в позиции {1}.', x, m);
exit;
end
else if x > a[m] then
begin
l := m + 1;
m := NewMiddle();
end
else
begin
r := m - 1;
m := NewMiddle();
end
end;
WritelnFormat('Не обнаружено элемента со значением {0}.', x);
end;
begin
SetLength(A, N);
for var i := 0 to N - 1 do
A[i] := Random(10);
Sort(A, 0, N - 1);
Writeln(A);
BinarySeach(A, 4, 0, N - 1);
end.
Смотрите также: реализация на Python
Математические задачи
правитьЗадача про фундамент
правитьВычислить значения все N при изначальном F1, шаге H и последнем F2. Причем, применялись формулы:
F = (N - RS) / (D - R), если F > 0.03S F = (N - RS) / D, если F ≤ 0.03S
begin
var F1 := ReadlnInteger('F1:');
var F2 := ReadlnInteger('F2:');
var H := ReadlnInteger('H:');
var R := ReadlnInteger('R:');
var S := ReadlnInteger('S:');
var D := ReadlnInteger('D:');
while F1 <= F2 do
begin
if F1 > 0.03 * S then
Writeln(F1 * (D - R) + R * S)
else
Writeln(F1 * D + R * S);
Inc(F1, H);
end;
end.
Треугольник с максимальным периметром
правитьconst
N = 6;
type
TPoint = auto class
X, Y: integer;
end;
TPointComparer = auto class(IEqualityComparer<TPoint>)
public
function Equals(a, b: TPoint) := (a.X = b.X) and (a.Y = b.Y);
function GetHashCode(a: TPoint) := 0;
end;
function Distance(a, b: TPoint) := Sqrt(Sqr(b.X - a.X) + Sqr(b.Y - a.Y));
function IsTriangle(a, b, c: TPoint): boolean;
begin
var d1 := Distance(a, b);
var d2 := Distance(b, c);
var d3 := Distance(c, a);
Result := (d1 + d2 <> d3) and (d2 + d3 <> d1) and (d3 + d1 <> d2);
end;
function Perimeter(a, b, c: TPoint) := Distance(a, b) + Distance(b, c) + Distance(c, a);
begin
var A := ReadArrInteger(N).Batch(2).Select(x -> new TPoint(x.First, x.Last)).Distinct(new TPointComparer()).ToArray();
Writeln(A);
var P := 0.0;
for var i := 0 to Length(A) - 1 do
for var j := i + 1 to Length(A) - 1 do
for var k := j + 1 to Length(A) - 1 do
begin
var P2 := Perimeter(A[i], A[j], A[k]);
if IsTriangle(A[i], A[j], A[k]) and (P2 > P) then
P := P2;
end;
if P > 0.0 then
WritelnFormat('Треугольник с максимальным P = {0} существует.', P)
else
Writeln('Треугольник с максимальным P не существует.');
end.
Разделы справки, которые могут помочь: |
---|
|
IEqualityComparer<T> - что такое?
Суммы цифр чисел файла
правитьvar
N, S: integer;
F: Text;
begin
Assign(F, 'C:\Ilya\AlgoРитмы\Сохраненные задачи\Файлы\test.txt');
Reset(F);
while not Eof(F) do
begin
Read(F, N);
while N <> 0 do
begin
S += N mod 10;
N := N div 10;
end;
WriteFormat('{0} ', S);
S := 0;
end;
Writeln();
Close(F);
end.
Ближайшая и дальняя точки
правитьconst
N = 4;
type
TPoint = record
X, Y: real;
Dist: real;
end;
var
A: array [0..N] of TPoint;
Found: boolean;
begin
for var i := 0 to N - 1 do
begin
A[i].X := ReadlnReal('X:');
A[i].Y := ReadlnReal('Y:');
A[i].Dist := Sqrt(Sqr(A[i].X) + Sqr(A[i].Y));
end;
var Min := real.MaxValue;
var MinI := 0;
for var i := 0 to N - 1 do
begin
if A[i].Dist < Min then
begin
Min := A[i].Dist;
MinI := i;
end;
end;
WritelnFormat('Ближняя точка {0} имеет расстоянее до начала координат, равное {1}.', MinI, Min);
Found := false;
for var i := 0 to N - 1 do
if (MinI <> i) and (Min = A[i].Dist) then
begin
WritelnFormat('Точка {0} также близка как ближайшая к началу координат.', i);
Found := true;
end;
if not Found then Writeln('Более ближайших точек не обнаружено.');
var Max := real.MinValue;
var MaxI := 0;
for var i := 0 to N - 1 do
begin
if A[i].Dist > Max then
begin
Max := A[i].Dist;
MaxI := i;
end;
end;
WritelnFormat('Дальняя точка {0} имеет расстоянее до начала координат, равное {1}.', MaxI, Max);
Found := false;
for var i := 0 to N - 1 do
if (MaxI <> i) and (Max = A[i].Dist) then
WritelnFormat('Точка {0} также далека как дальняя от начала координат.', i);
if not Found then Writeln('Более дальних точек не обнаружено.');
end.
Сортировка треугольников по возрастанию периметра
правитьconst
N = 3;
type
TPoint = record
X, Y: integer;
constructor(px, py: integer);
begin
X := px;Y := py;
end;
end;
TTriangle = record
A, B, C: TPoint;
P: real;
constructor(pA, pB, pC: TPoint);
begin
A := pA;B := pB;C := pC;
end;
end;
function ReadlnPoint() := new TPoint(ReadlnInteger('X:'), ReadlnInteger('Y:'));
function Distance(pA, pB: TPoint) := Sqrt(Sqr(pA.X - pB.X) + Sqr(pA.Y - pB.Y));
function PointToString(p: TPoint) := Format('({0}, {1})', p.X, p.Y);
function TriangleToString(t: TTriangle) := Format('Triangle: A{0}, B{1}, C{2}, P = {3}.', PointToString(t.A), PointToString(t.B), PointToString(t.C), t.P);
var
A: array [0..N - 1] of TTriangle;
begin
for var i := 0 to N - 1 do
begin
Writeln('New triangle:');
A[i] := new TTriangle(ReadlnPoint(), ReadlnPoint(), ReadlnPoint());
A[i].P := Distance(A[i].A, A[i].B) + Distance(A[i].B, A[i].C) + Distance(A[i].C, A[i].A);
end;
for var i := 0 to N - 1 do
for var j := i + 1 to N - 1 do
if A[i].P > A[j].P then
Swap(A[i], A[j]);
for var i := 0 to N - 1 do
Writeln(TriangleToString(A[i]));
end.
Дальние треугольники
правитьconst
N = 6;
type
TPoint = auto class
X, Y: real;
end;
var
L: List<(TPoint, TPoint, TPoint)>;
Max: real;
i1, i2: integer;
begin
L := new List<(TPoint, TPoint, TPoint)>();
for var i := 1 to N do
L.Add((new Point(ReadlnInteger('X1:'), ReadlnInteger('Y1:')),
new Point(ReadlnInteger('X2:'), ReadlnInteger('Y2:')),
new Point(ReadlnInteger('X3:'), ReadlnInteger('Y3:'))
));
Max := real.MinValue;
for var i := 0 to N - 1 do
for var j := i + 1 to N - 1 do
begin
var p1 := new TPoint((L[i].Item1.X + L[i].Item2.X + L[i].Item3.X) / 3,
(L[i].Item1.Y + L[i].Item2.Y + L[i].Item3.Y) / 3);
var p2 := new TPoint((L[j].Item1.X + L[j].Item2.X + L[j].Item3.X) / 3,
(L[j].Item1.Y + L[j].Item2.Y + L[j].Item3.Y) / 3);
var d := Sqrt(Sqr(p1.X - p2.X) + Sqr(p1.Y - p2.Y));
if d > Max then
begin
i1 := i;
i2 := j;
Max := d;
end;
end;
WritelnFormat('Индексы дальних треугольников: {0} и {1}.', i1, i2);
end.
Более сложные задачи
правитьКонвертирование числа в строку
правитьconst
S = '0123456789ABCDEF';
function ToString(a, base: integer): string;
begin
while a <> 0 do
begin
Result := S.Chars[a mod base + 1] + Result;
a := a div base;
end;
end;
function ToStringRecursive(a, base: integer): string;
begin
if a <> 0 then
Result := S.Chars[a mod base + 1] + Result
else
Result := ToString(a div base, base);
end;
begin
Writeln(ToString(15, 2) = ToStringRecursive(15, 2));
end.
Задача о детях
правитьconst
N = 3;
type
TPerson = auto class
Surname, Name: string;
Year: integer;
Mass, Height: integer;
end;
var
A: array of TPerson;
begin
SetLength(A, N);
for var i := 0 to N - 1 do
begin
var p := ReadlnString().ToWords();
A[i] := new TPerson(p[0], p[1], StrToInt(p[2]), StrToInt(p[3]), StrToInt(p[4]));
end;
A.Where(x -> begin
var d := 2017 - x.Year;
Result := (d >= 10) and (d <= 12) and (x.Height >= 155) and (x.Mass <= 45)
end).Select(x -> Format('{0} {1} {2} {3} {4}', x.Surname, x.Name, x.Year, x.Mass, x.Height)).Println();
end.
Потенциальные друзья
правитьШкола юных программистов решила разработать собственную социальную сеть, которая должна автоматически подбирать для каждого пользователя потенциальных друзей. При регистрации каждому пользователю сети предлагается пройти психологическое тестирование, по результатам которого определяются значения трёх психологических характеристик этого пользователя. Значение каждой характеристики — целое положительное число.
Считается, что если у двух пользователей различаются значения всех трёх психологических характеристик, то они будут постоянно ссориться, а если совпадают значения двух или трёх характеристик, то им будет скучно. Таким образом, потенциальными друзьями являются только такие пары пользователей, у которых совпадают значения ровно одной характеристики, а значения двух других — различаются.
Требуется написать программу, которая по данным тройкам значений характеристик каждого из пользователей определяет количество пар потенциальных друзей.
var
A: array of (integer, integer, integer);
Count: integer;
begin
SetLength(A, ReadlnInteger('Количество людей:'));
for var i := 0 to A.Length - 1 do
begin
var p := ReadlnString().ToWords().ConvertAll(x -> StrToInt(x));
A[i] := (p[0], p[1], p[2]);
end;
for var i := 0 to A.Length - 1 do
for var j := i + 1 to A.Length - 1 do
if Ord(A[i].Item1 = A[j].Item1) + Ord(A[i].Item2 = A[j].Item2) + Ord(A[i].Item3 = A[j].Item3) = 1 then
Inc(Count);
Writeln(Count);
end.
//Аналог через готовые методы.
begin
var A := Range(1, ReadlnInteger('Количество людей')).Select(i -> ReadlnString().ToIntegers()).ToArray();
Writeln(A.Cartesian(A, (v, t) -> Ord(v[0] = t[0]) + Ord(v[1] = t[1]) + Ord(v[2] = t[2])).Count(v -> v = 1) div 2);
end.
Хорошисты и отличники
правитьВывести фамилии и имена студентов, сдавших 3 экзамена на 4 или 5.
type
TAssessments = (integer, integer, integer, integer);
TStatement = record
Surname, Name: string;
Assessments: TAssessments;
constructor(s, n: string; a: TAssessments);
begin
Surname := s;Name := n;
Assessments := a;
end;
end;
var
L: List<TStatement>;
function F(a: integer) := (a = 4) or (a = 5);
begin
L := new List<TStatement>();
for var i := 0 to ReadlnInteger('N:') - 1 do
begin
var p := ReadlnString().ToWords();
var k := p.Skip(2).ToList().ConvertAll(x -> StrToInt(x));
L.Add(new TStatement(p[0], p[1], (k[0], k[1], k[2], k[3])));
end;
Writeln('Сдали 3 экзамена на 4 или 5:');
L.Where(x -> Ord(F(x.Assessments.Item1)) + Ord(F(x.Assessments.Item2)) + Ord(F(x.Assessments.Item3)) + Ord(F(x.Assessments.Item4)) = 3).
Select(x -> Format('{0} {1}', x.Surname, x.Name)).JoinIntoString(NewLine).Println();
Writeln('Не сдали экзамены:');
L.Where(x -> (x.Assessments.Item1 < 3) or (x.Assessments.Item2 < 3) or (x.Assessments.Item3 < 3) or (x.Assessments.Item4 < 3)).
Select(x -> Format('{0} {1}', x.Surname, x.Name)).JoinIntoString(NewLine).Println();
end.