Циклические, повторяющиеся много раз однотипные вычисления позволяют наилучшим образом продемонстрировать вычислительные возможности компьютеров. Ради этого их изначально и создавали. В задачах этого раздела желательно снова перечитать параграф 5.4 из праймера посвященный «итерационным операторам» (так они назвали семейство из нескольких операторов цикла). Часть 5.4.3 можете пока пропустить, поскольку мы еще не изучали структур данных для которых … Continue reading →
В некотором учебном заведении функционирует кружок хорового пения. Начало кружка всегда происходит единообразно: по сигналу руководителя кружка все [latex]N[/latex]участников становятся в круг и каждый [latex]M[/latex]-й для распевки поёт гамму.
Руководитель кружка заметил, что размять голосовые связки не всегда удаётся всем участникам кружка. По заданным [latex]N[/latex] и [latex]M[/latex] помогите ему определить, или в очередной раз в разминке примут участие все участники хора.
Входные данные
Входные данные состоят из нескольких тестовых случаев. Каждый тестовый случай расположен в отдельной строке и содержит два целых числа [latex]N[/latex] и [latex]M[/latex], где [latex]\left( 1 \le N, M \le {10}^{3} \right).[/latex]
Выходные данные
Для каждого тестового случая в отдельной строке выведите «YES», если в разминке примут участие все участники хора, в противном случае выведите «NO».
Тесты:
n
m
answer
4
1
YES
6
3
NO
Решение:
Для начала нам надо найти наибольший общий делитель(НОД). Для этого хорошо подойдет алгоритм Евклида и если НОД равен единице то все ученики распоются и мы выводим «YES» в другом случае мы выводим «NO».
Известно, что в школе не менее чем [latex]k_1[/latex] учеников, но не более чем [latex]k_2[/latex] учеников. Также известно, что каждый мальчик дружит с [latex]n[/latex] девочками, а каждая девочка с [latex]m[/latex] мальчиками. Какое минимальное количество учеников может быть в школе, и сколько в школе мальчиков и девочек?
Тесты:
№
Ввод
Вывод
1
20 30 4 5
27 15 12
2
40 50 5 4
45 20 25
Код программы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
usingnamespacestd;
intmain(){
intk1,k2,n,m;
intb,g;//b-boys;g-girls
cin>>k1>>k2>>n>>m;
for(g=n;true;g++)
{
b=g*m/n;
if(((g*m)%n)==0&&b+g>=k1)break;// перебираем варианты пока количество мальчиков не станет целым а сумма всех учеников будет больше k1
}
cout<<b+g<<" "<<b<<" "<<g<<endl;
return0;
}
Решение:
Увеличиваем количество девочек на 1 пока количество мальчиков по формуле [latex]b = g \cdot m / n[/latex] не станет целочисельным значением и сумма мальчиков и девочек будет больше или равна минимальному возможному количеству учеников [latex]k_1[/latex].
Вычислить количество цифр целого неотрицательного числа [latex]n[/latex].
Входные данные
Одно не отрицательное целое число [latex]n[/latex] [latex](0<=n<=2*10^9)[/latex].
Выходные данные
Количество цифр в числе [latex]n[/latex].
Тесты
Число
Количество цифр
1
1
20
2
123
3
Код
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
usingnamespacestd;
intmain(){
intx,n=1;
cin>>x;
while((x/=10)>0)n++;
cout<<n;
return0;
}
Решение
Сначала объявляем переменную [latex] n [/latex] для подсчета цифр в числе и присваиваем ей значение 1. Далее используем цикл while, проверкой которого ставим деление числа на 10 — так как тип числа int, это «отбрасывает» последнюю цифру в числе. Пока результат проверки истинный, инкриментируем n на 1.
Альтернативное решение с помощью десятичного логарифма
Сначала проверяется, не является ли введенное число нулем, так как невозможно посчитать любой логарифм от нуля. Если число отлично от нуля, находим десятичный логарифм от числа, прибавляем к нему единицу (что соответствует количеству цифр в числе). Берем целую часть от найденного, в случае, если число не кратно 10.
Ученикам первого класса дополнительно дают стакан молока и пирожок, если вес первоклассника менее 30 кг. В первых классах школы учится [latex]n[/latex] учеников. Стакан молока имеет емкость 200 мл, а упаковки молока – 0.9 л. Определить количество дополнительных пакетов молока и пирожков, необходимых каждый день.
Тесты
Количество детей
Вес
Количество упаковок молока
Количество пирожков
3
30 29 30
1
1
5
25 41 56 20 20
1
3
4
30 30 30 30
0
0
7
25 26 27 28 29 23 24
2
7
Код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <cmath>
usingnamespacestd;
intmain(){
intp=0;//пирожки
intn,k;//количество детей, вес и упаковки молока
doublem,u,w;
cin>>n;
m=0.2;u=0.9;
for(inti=0;i<n;i++){
cin>>w;
if(w<30)p++;
if(w>=30)p=p+0;
}
k=ceil(p*m/u);
cout<<k<<" "<<p;
return0;
}
Решение
Возьмем количество пирожков за счетчик. Используя for найдем количество пирожков для детей, вес которых не превышает 30кг.
По количеству пирожков мы можем найти количество упаковок молока. При этом мы можем получить не целое число. Чтобы избежать этого, подключаем библиотеку <cmath> и используем округление вверх ceil .
Приближается Новый год! Третьеклассники уже мечтают побывать возле новогодней елки в Киеве. Учительница математики одного из 3-х классов г. Александрия им сообщила, что она сможет свозить на ёлку в Киев только тех учеников, которые решать задачку от святого Николая. Он хочет узнать качество заданного числа.
По мнению Николая, качеством числа [latex]N[/latex] является сумма цифр всех натуральных чисел [latex] A[/latex] не больших самого числа [latex] N[/latex] таких что остаток от деления числа [latex] N[/latex] на число [latex] A[/latex] равен [latex] 0[/latex] .
Входные данные
Первая строка содержит натуральное число [latex]N[/latex] – количество учеников в 3-м классе. В последующих [latex]N[/latex] строках размещены задания для каждого ученика: натуральное число не больше чем [latex] 15 000 000[/latex] (Николай решил пожалеть учеников и числа выбрал не очень большие)
Выходные данные
Для каждого из чисел, заданных Николаем ученикам, укажите его качество.
Код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <cmath>
usingnamespacestd;
intSumOfDigit(intn){
intf=0;
while(n>=1){
f+=n%10;
n/=10;
}
returnf;
}
intmain()
{
intN;
cin>>N;
for(inti=1;i<=N;i++){
intA;
cin>>A;
intsum=0;
doublef=sqrt(A);
for(intj=1;j*1.0<=f;j++){
if(A%j==0)sum+=SumOfDigit(j)+SumOfDigit(A/j);
}
if((int)f==f)sum-=f;
cout<<sum<<endl;
}
return0;
}
Тесты:
Количество строк
1 задание
2 задание
Вывод
2
2
10
3; 9
2
2
1500000
3; 666
2
5
9
6; 13
2
60
15000000
42; 978
2
1
0
1; 0
Решение
В данной задаче я выделил отдельную функцию — [latex]SumOfDigit()[/latex]. Не трудно догадаться, что она считает сумму цифр числа для будущих вычислений. Для первого цикла мы сначала должны ввести число [latex]N[/latex] — количество заданий для учеников. Именно столько раз будет выполняться основной цикл. Чтобы определить качество числа, необходимо найти все его натуральные делители. Для решения данной задачи я воспользовался методом перебора всех чисел до корня из исходного, что значительно ускоряет вычисление по сравнению с перебором вплоть до самого числа. Во внутреннем цикле проверяется каждое число, и если оно удовлетворяет условию, то вызывается функция [latex]SumOfDigit[/latex], а в переменную [latex]sum[/latex] записываются значения сумм.
C++
1
if((int)f==f)sum-=f;
Данная строка необходима для проверки, если исходное число является квадратом.
В конце основного цикла программа печатает на экран качество данного числа.
Данная задача решалась совместно со Стасом Коциевским на факультативе.
В некотором царстве жил Змей Горыныч. У него было [latex]N[/latex] голов и [latex]M[/latex] хвостов. Иван-царевич решил уничтожить губителя человеческих душ, для чего ему его кума Баба Яга подарила волшебный меч, так как только им можно убить Змея Горыныча. Если отрубить одну голову, то на её месте вырастает новая, если отрубить хвост, то вместо него вырастет 2 хвоста. Если отрубить два хвоста, то вырастает 1 голова, и только когда отрубить 2 головы, то не вырастет ничего. Змей Горыныч гибнет только в том случае, когда ему отрубить все головы и все хвосты. Определить минимальное количество ударов мечом, нужное для уничтожения Змея Горыныча.
Входные данные:
Два числа [latex]N[/latex], [latex]M[/latex] ([latex]0[/latex] [latex]<=[/latex][latex]N[/latex], [latex]M[/latex][latex]<=[/latex][latex]1000[/latex]).
Выходные данные:
Единственное число – минимальное количество ударов мечом, или
-1, если уничтожить Змея Горыныча невозможно.
Тесты:
N
M
Количество ударов
3
3
9
3
0
-1
0
9
12
0
0
0
3
2
3
19
114
95
Решение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
usingnamespacestd;
intmain(){
intN,M,count=0;
cin>>N>>M;
if((N%2!=0)&&(M==0))//здесь проверяется, возможно ли убить Горыныча
{
cout<<"-1"<<endl;// вывод "-1" в противном случае
}
else
{
while((N>0)||(M>0))//цикл будет выполняться до тех пор, пока существует хоть одна голова или хвост
{
if(M%2==1)//если хвостов нечетное количество, то посредством отрубания одного хвоста увеличиваем число их на 1
{
count++;// здесь и далее таким образом будет увеличиваться счетчик надрезов
M++;
}
if((N%2==1)&&(M>=2))//если голов нечетное количество, то отрубая два хвоста увеличиваем количество голов на 1
{
M-=2;
N++;
count++;
}
if((M%2==0)&&(N%2==0)&&((N+(M/2))%2==0))//если число голов и хвостов четное, и если количество хвостов при делении на два дает четное число
M=0;//и обнуляем количество голов и хвостов для выхода их цикла
}
else//если не выполняется какое-либо из условий прошлого ветвления, то увеличиваем количество хвостов на 1
{
M++;
count++;
}
}
cout<<count<<endl;//выводим количество ударов
}
return0;
}
Описание решения:
При решении данной задачи было рассмотрено несколько случаев.
Змея Горыныча убить невозможно. Это возможно только в том случае, когда у него нечетное количество голов, и нет ни одного хвоста, так как при наличии хотя бы одного хвоста становится возможным увеличение количества хвостов и голов до необходимого, путем отрубания одного, или двух хвостов соответственно. Чтобы определить возможность уничтожения Змея, делаем проверку: если количество голов нечетное и хвостов нет, то выводим «-1». Если эти условия не выполняются, то переходим ко второму пункту решения.
Змей Горыныч может быть убит. Это означает, что у Змея есть хотя бы один хвост, или четное количество голов. В таком случае, мы работаем внутри цикла, при каждом проходе которого проверяется, выполняются ли описанные выше условия:
C++
13
while((N>0)||(M>0))//цикл будет выполняться до тех пор, пока существует хоть одна голова или хвост
Горыныча можно убить тогда и только тогда, когда при отрубании всех хвостов получается четное количество голов. Отсюда, необходимо, чтобы у Змея было четное количество хвостов, и сумма голов и количества хвостов, деленного на два, была четным числом. Поэтому будем работать по простому алгоритму:
Если количество хвостов [latex]M[/latex] нечетное, то отрубаем один хвост, на месте которого вырастает два новых, и увеличиваем счетчик ударов [latex]count[/latex] на один.
Если количество голов нечетное, и хвостов больше одного, то отрубаем два хвоста, тем самым увеличивая количество голов на 1, и увеличиваем счетчик.
Если количество голов и хвостов четное, и если количество хвостов при делении на два дает четное число, то мы увеличиваем счетчик на [latex]M/2+((N+M/2)/2)[/latex], и приравниваем количество голов и хвостов нулю.
Если какое-то из условий пункта 3 не выполняется, то увеличиваем количество хвостов на 1, и увеличиваем счетчик ударов.
Повторяем алгоритм до тех пор, пока не убьем Горыныча.
После выхода из цикла в счетчике [latex]count[/latex] находится минимальное число ударов, необходимое для уничтожения Змея Горыныча. Выводим его на экран, и переходим на новую строку с помощью команды [latex]endl[/latex].
Возьмем какое-нибудь натуральное число [latex]N[/latex]. Будем изменять его следующим образом: если число четное, то разделим его на 2, если нечетное, прибавим 1. После нескольких таких изменений мы всегда получаем число 1. Например, из числа 11 получается число 12, затем 6, 3, 4, 2 и, наконец, 1. Таким образом, для получения 1 из 11 нужно проделать 6 изменений.
Напишите программу, которая считывает натуральное число и выводит количество изменений данного числа до получения 1.
Пусть [latex]N[/latex] — это число, которое мы будем изменять, а [latex]counter[/latex] — количество превращений. Цикл должен выполняться до того момента, пока [latex]N \neq 1[/latex]. Чтоб проверить число на чётность/нечётность, делим его по модулю и сравниваем остаток с нулём. Если число — чётное, то делим его на 2, в противном случае — добавляем единицу, и при выполнении каждого действия, увеличиваем количество превращений на 1.
Задача. Дана рациональная дробь [latex]\frac{m}{n}[/latex]. Запишите её в виде десятичной дроби с точностью [latex] k[/latex] знаков после запятой.
Входные данные
В одной строке записано 3 числа [latex]m,n,k[/latex]. [latex]{{0}<{m,n}\leq{100}}[/latex], [latex]{{0}\leq{k}\leq{1000}}[/latex].
Выходные данные
Вывести [latex]k[/latex] точных значащих цифр после десятичной точки искомого числа.
Алгоритм решения:
Деление уголком
Разделим [latex]m[/latex] на [latex]n[/latex] в столбик. Определим, сколько раз [latex]n[/latex] помещается в [latex]m[/latex]. Это будет целая часть частного. Умножим ее на [latex]n[/latex] и отнимем от [latex]m[/latex]. Таким образом получим остаток от деления. Будем умножать его на [latex]10[/latex] (эквиваленто сноске [latex]0[/latex]) и проводить такую же операцию, как при нахождении целой части пока не закончится цикл. Так мы определим все цифрs после запятой.
Назовем число «зеркально простым», если само число является простым, и простым является число, записанное теми же цифрами в обратном порядке.
Найти количество «зеркально простых» чисел на промежутке от [latex]a[/latex] до [latex]b[/latex].
Входные данные
Два числа [latex]a[/latex] и [latex]b[/latex] ( [latex]1[/latex][latex]\le[/latex] [latex]a[/latex], [latex]b[/latex] [latex]\le[/latex] [latex]10000[/latex]).
Выходные данные
Вывести количество «зеркально простых» чисел на промежутке от [latex]a[/latex] до [latex]b[/latex] включительно.
Перед нами была поставлена задача реализовать поиск всех «зеркально простых» чисел на заданном промежутке. Проверив в правильном ли порядке введены границы промежутка, организуем последовательный анализ для каждого числа из промежутка в теле главного цикла :
Инициализируем две логические переменные, значение которых отвечает за прохождение теста на простоту самим числом и «зеркальным» соответственно.
Методом последовательного перебора делителей определяем является ли данное число простым. Если данное утверждение истинно, переходим к последующим пунктам. В противном случае переходим на новый виток главного цикла.
Выполняем последовательную сборку числа, записанного в обратном порядке.
Проводим аналогичную проверку на простоту для «зеркального» числа.
При условии, что это число также является простым, инкрементируем счетчик.
Достигнув верхней границы промежутка, выводим количество «зеркально простых» чисел.
Код программы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
usingnamespacestd;
intmain(){
inta,b;
intnumber1,number2;// переменные для хранения текущего числа из промежутка и "зеркального" соответственно
intcounter=0;// счетчик количества "зеркально простых" чисел
cin>>a>>b;
if(a>b){
a+=b;
b=a-b;
a-=b;
}// меняем местами границы промежутка, если они введены в неправильном порядке
if(a==1)
counter--;// декрементируем счетчик, если в промежуток попадает число 1, которое не является простым
for(inti=a;i<=b;i++){
number1=i;
boolf1=true;// флаг выполнения условия для number1
boolf2=true;// флаг выполнения условия для number2
Для нумерации [latex]M[/latex] страниц книги использовали [latex]N[/latex] цифр. По заданному [latex]N[/latex] вывести [latex]M[/latex] или [latex]0[/latex], если решения не существует. Нумерация начинается с первой страницы.
Входные данные
Единственное число [latex]N[/latex]. В книге не более [latex]1001[/latex] страницы.
Выходные данные
Искомое количество страниц.
Тесты :
N
8
21
22
113
999
1001
M
8
15
0
61
369
0
Код программы
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
usingnamespacestd;
intmain()
{
intN;
cin>>N;
for(inti=1;true;i++)// i - номер страницы, будем отнимать от N количество цифр в i
{
if(i<10)// в i одна цифра
N--;
elseif(i>=10&&i<100)// 2 цифры
N-=2;
elseif(i>=100&&i<1000)// 3 цифры
N-=3;
else// 4 цифры
N-=4;
if(N==0)// если лишних цифр у нас не осталось
{
cout<<i<<endl;
break;
}
elseif(N<0)// иначе выводим "0"
{
cout<<0<<endl;
break;
}
}
return0;
}
Примечание
Общее (и более компактное) решение можно написать, подключив библиотеку <cmath> и воспользовавшись функцией логарифма с основанием 10.
Код программы (вторая версия)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <cmath>
usingnamespacestd;
intmain()
{
intN;
cin>>N;
for(inti=1;true;i++)// i - номер страницы, будем отнимать от N количество цифр в i
Задача. Подсчитайте количество счастливых билетов, у которых сума первых трёх цифр равна [latex]N(N \leq 27)[/latex].
Счастливым билетом называется билет с шестизначным номером, у которого сумма первых трёх цифр равна сумме трёх последних.
Тесты
Число [latex]N[/latex]
3
27
26
1
10
Количество билетов
100
1
9
9
3969
Код программы
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
usingnamespacestd;
intmain()
{
intN,c=0;
cin>>N;
for(inti=0;i<10;i++)//цикл, перебирающий все варианты первой цифры трехзначного числа
{
for(intj=0;j<10;j++)//вложенный цикл, перебирающий все варианты второй цифры
{
if(N-i-j>=0&&N-i-j<10)//условие для третьей цифры
{c++;}//подсчет подходящих номеров
}
}
cout<<c*c;//увеличение количества в c раз для шестизначного числа
return0;
}
Алгоритм
Любой шестизначный номер мы можем представить как 2 трехзначных номера.
Рассмотрим все варианты трехзначных номеров. Две первые цифры такого номера могут быть любыми. Переберем все их комбинации с помощью двух вложенных циклов. Для третьей цифры введем специальное условие. Она должна быть результатом вычитания двух первых цифр из [latex]N[/latex], а также быть именно цифрой, то есть меньшей 10.
Когда в цикле встречается подходящая комбинация, мы увеличиваем счетчик [latex]c[/latex] на 1. Поскольку на самом деле номер шестизначный, то каждой удачной комбинации в первой его половине будет соответствовать [latex]c[/latex] комбинаций во второй. Следовательно, искомое число счастливых билетов будет равно [latex]c \cdot c[/latex].
Задано натуральное [latex]M[/latex]. Если число не палиндром – записываем его в обратном порядка и слагаем с заданным. Действия повторяем до тех пор, пока не получим число-палиндром. Количество выполненных операций назовем уровнем палиндромности заданного числа.
Найти уровень палиндромности заданного числа [latex]M[/latex].
Входные данные
Единственное число [latex]M[/latex] ([latex]0[/latex] [latex] <[/latex] [latex]M[/latex] [latex] <[/latex] [latex]10000[/latex]).
В данной задаче для заданного числа требуется определить уровень его палиндромности — количество раз, которое придется просуммировать его с обратным ему числом до получения палиндрома.
Для начала инициализируем счетчик, который хранит в себе текущее значение уровня палиндромности, и логическую переменную, значение которой ложно до тех пор пока палиндром не найден. Данное условие и будет критерием для выполнения тела основного цикла.
Присвоив значения переменным в цикле, выполняем последовательный разбор введенного числа на цифры и сборку «зеркального» числа.
Проверяем равенство числа и ему обратного.
Выполнение условного оператора сигнализирует о том, что палиндром найден, следовательно выводим «уровень», изменяем значение логической переменной на противоположное и выходим из цикла.
В противном случае суммируем текущее число и «зеркальное», инкрементируем счетчик.
Повторяем пункты 2, 3, 5 до истинности пункта 3 и перехода к 4.
Код программы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
usingnamespacestd;
intmain(){
longx,x1,x2;// переменные для хранения числа, его копии и числа записанного в обратном порядке соответственно
intc;
intk=0;// счетчик "уровня палиндромности"
cin>>x;
boolf=false;// флаг выполнения условия палиндромности числа
while(!f){
x1=x;
x2=0;
while(x1>0){
c=x1%10;
x1/=10;
x2=x2*10+c;// собираем число записанное в обратном порядке
}
if(x==x2){
cout<<k;// выводим счетчик, если число палиндром
f=true;
break;// выход из цикла, при условии, что палиндром найден
}else{
x+=x2;// суммируем значение числа и обратно записанного, если оно не является палиндромом
Для решения данной задачи я вывел две функции, до главной, а именно — функцию умножения цифр натурального числа и функцию сложения цифр натурального числа, которыми воспользуемся в дальнейшем.
В главной же функции мы выводим отношение произведения цифр к их сумме, округленное до третьего знака после запятой.
Задача. Указать маршрут коня. Начинающегося на одном заданном поле шахматной доски и оканчивающемся на другом. Никакое поле не должно встречаться в маршруте дважды.
Читаем входные данные. Преобразуем их в координаты начального и финального поля на шахматной доске. Массив chessboard сначала заполняем -1 (не пройденные поля), затем значение в поле с начальными координатами присваиваем 0. Затем будем отмечать все доступные ходы коня до тех пор пока не изменится значение в финальном поле. Затем, если у нас не совпали начальное и финальное поле будем восстанавливать путь коня. Создаем массив в котором и будет путь коня. Первое значение которое мы заносим в массив будет наше финальное поле. Затем с этого поля будем рассматривать все возможные ходы которые пройдут по уже помеченным клеткам. Если в финальное поле можно было попасть несколькими путями одинаковой длины то нам не имеет значение каким из них возвращаться в начальное поле. Затем выводим массив пути в обратном порядке.
Там были приведены алгоритмы генерирования перестановок («Комбинаторные алгоритмы», стр. 27-29) и генерирования сочетаний («Комбинаторика для программистов», стр. 39-41).
Размещения я получал следующим образом:
Посчитал кол-во всевозможных размещений по формуле [latex]A^{k}_{n}=\frac{n!}{(n-k)!}=\frac{9!}{4!}=15120[/latex];
Заметил, что размещения — это перестановки всех уникальных комбинаций из 5 чисел (т.е сочетаний);
Поскольку кол-во перестановок [latex]P_{k}=k![/latex], а кол-во сочетаний — [latex]C_{n}^{k}=\frac{n!}{k!(n-k)!}[/latex], то кол-во размещений [latex]A_{n}^{k}=P_{k}\times{C_{n}^{k}}=\frac{n!k!}{k!(n-k)!}=\frac{n!}{(n-k)!}=15120[/latex];
Таким образом, генерируя вначале сочетание, я генерировал перестановки этого сочетания. В результате вышло 15120 размещений.
Ориентированный граф задан матрицей смежности.
Найдите количество ребер в графе.
Входные данные
Входной файл содержит число n (1 ≤ n ≤ 100) — число вершин в графе, и затем n строк по n чисел, каждое из которых равно 0 или 1 — его матрицу смежности.
Выходные данные
Выведите в выходной файл количество ребер заданного графа.
Алгоритм решения прост. Количество ребер ориентированного графа равно количеству единиц в его матрице смежности. Поэтому просто считываем, суммируем если 1, и выводим ответ.
Комплексная матрица [latex]Z[/latex] представляется парой [latex]X[/latex], [latex]Y[/latex] действительных матриц так, что [latex]Z=X+iY[/latex]. Даны действительные квадратные матрицы [latex]A[/latex], [latex]B[/latex], [latex]C[/latex] и [latex]D[/latex] порядка [latex]m[/latex]. Найти произведение двух комплексных матриц [latex]A+iB[/latex] и [latex]C+iD[/latex], т. е. найти действительные квадратные матрицы [latex]X[/latex] и [latex]Y[/latex] порядка [latex]m[/latex] такие, что [latex]X+iY=(A+iB)(C+iD)[/latex].
Дан неориентированный невзвешенный граф, в котором выделена вершина. Вам необходимо найти количество вершин, лежащих с ней в одной компоненте связности (включая саму вершину).
Входные данные
В первой строке содержится два целых числа [latex]n[/latex] и [latex]s[/latex] [latex](1\leq s\leq n\leq 100)[/latex], где [latex]n[/latex] — количество вершин графа, а [latex]s[/latex] — выделенная вершина. В следующих [latex]n[/latex] строках записано по [latex]n[/latex] чисел — матрица смежности графа, в которой цифра «0» означает отсутствие ребра между вершинами, а цифра «1» — его наличие. Гарантируется, что на главной диагонали матрицы всегда стоят нули.
Выходные данные
Выведите одно число — искомое количество вершин.
Пример:
Входные данные
Выходные данные
5 1
3
0 1 1 0 0
1 0 1 0 0
1 1 0 0 0
0 0 0 0 1
0 0 0 1 0
Решение
Обход в глубину
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <stack>
usingnamespacestd;
intmain()
{
intn;
ints;
cin>>n>>s;
s--;
intmatrix[n][n];
stack<int>st;
intcounter=1;
for(inti=0;i<n;i++)
{
for(intj=0;j<n;j++)
{
cin>>matrix[i][j];
}
}
for(intj=0;j<n;j++)
{
if(matrix[s][j]==1)st.push(j);
}
matrix[s][s]=1;
while(!st.empty())
{
inta=st.top();
st.pop();
if(matrix[a][a]!=1)
{
for(intj=0;j<n;j++)
{
if(matrix[a][j]==1)st.push(j);
}
counter++;
matrix[a][a]=1;
}
}
cout<<counter<<endl;
}
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
importjava.util.*;
importjava.lang.*;
importjava.io.*;
classIdeone
{
publicstaticvoidmain(String[]args)
{
Scanner in=newScanner(System.in);
intn=in.nextInt(),s=in.nextInt()-1,counter=1;
int[][]matrix=newint[n][n];
Stack st=newStack();
for(inti=0;i<n;i++)
{
for(intj=0;j<n;j++)
{
matrix[i][j]=in.nextInt();
}
}
for(intj=0;j<n;j++)
{
if(matrix[s][j]==1)st.push(j);
}
matrix[s][s]=1;
while(!st.empty())
{
inta=(int)st.peek();
st.pop();
if(matrix[a][a]!=1)
{
for(intj=0;j<n;j++)
{
if(matrix[a][j]==1)st.push(j);
}
counter++;
matrix[a][a]=1;
}
}
System.out.println(counter);
}
}
Вводим данные, затем в первом цикле проверяем строку [latex]s[/latex], и записываем в стек все вершины инцидентные данной. Так как в условии гарантируется наличие на главной диагонали нулей, то будем помечать проверенные вершины с помощью элемента расположенного на главной диагонали (то есть будем присваивать ему значение отличное от 0, к примеру 1). После будем проверять все строки в стеке до его опустошения, и увеличивать счётчик на единицу после удаления из стека не помеченной вершины.
Даны натуральное число [latex]n,[/latex] действительные числа [latex]a_{1},\ldots,a_{n}[/latex].
Вычислить: [latex]\sqrt{10+a_{1}^{2}}+\ldots+\sqrt{10+a_{n}^{2}}[/latex]
n
[latex]a_{1}[/latex]
[latex]a_{2}[/latex]
[latex]a_{3}[/latex]
[latex]a_{4}[/latex]
[latex]a_{5}[/latex]
[latex]a_{6}[/latex]
sum
Комментарий
6
1
0.5
7
19
-9
8
51.6024
Пройден.
5
16
14.3
2
27
19
—
81.1426
Пройден.
2
61
-5
—
—
—
—
66.998
Пройден.
3
28.8
0.34
20.9
31.5
—
—
53.2915
Пройден.
1
-65.9242
—
—
—
—
—
66
Пройден.
Massive
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <math.h>
usingnamespacestd;
intmain()
{
inti;
intn;
doublesum=0;
cin>>n;
doublea;
for(i=1;i<=n;++i)
{
cin>>a;
sum+=sqrt(10+a*a);
}
cout<<sum;
return0;
}
Вводим числа( n, [latex]a_{1},\ldots,a_{k}.[/latex])
Дана целочисленная матрица [latex][a_{ij}], ij=1,\ldots,n.[/latex] Получить [latex]b_{1},\ldots,b_{n}[/latex], где [latex]b_{i}[/latex] — это: [latex]\underset{1\leq j\leq n}{\max a_{ij}}\cdot \underset{1\leq j\leq n}{\min a_{ji}}[/latex].
Исходя из задачи ясно, что из данной матрицы надо взять максимальный элемент [latex]i[/latex]-й строки и умножить его на минимальный элемент [latex]i[/latex]-го столбца. Так например, если нам дана матрица 2-го порядка [latex]\begin{Vmatrix}1&2\\4&1\end{Vmatrix}[/latex] то [latex]b_{1}= 2[/latex], [latex]b_{2}= 4[/latex].
Для нахождения максимума [latex]a_{ij}[/latex], введем переменную и будем придавать ей начальное значение 1-го элемента [latex]i[/latex]-й строки. Дабы при расчете максимума проходя по элементам строки мы не сравнивали каждый [latex]i[/latex]-й элемент с 1-м, придавать начальное значение максимуму мы будем в цикле по [latex]i[/latex]. Аналогично с минимумом [latex]a_{ji}[/latex], одно единственное но, начальное значение минимума будет равно первому элементу [latex]i[/latex]-го столбца.
Тесты:
Матрица порядка [latex]n[/latex], где [latex]n[/latex]:
Для отправки комментария необходимо войти на сайт.