Книга программиста/Задачи на 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.