Задача
Мудрый король решил ввести новый календарь. «Завтра будет первый день календаря, то есть день [latex]1[/latex] месяца [latex]1[/latex] года [latex]1[/latex]. Каждый год состоит из [latex]10[/latex] месяцев, с [latex]1[/latex] по [latex]10[/latex], и начинается с большого месяца. Обычный год начинается с большого месяца, за которым следует малый месяц, затем большой месяц и так далее один за другим. То есть первый месяц большой, второй малый, третий большой, …, десятый, он же последний, малый. Большой месяц состоит из [latex]20[/latex] дней, а малый месяц из [latex]19[/latex] дней. Однако годы, кратные трем, то есть год [latex]3[/latex], год [latex]6[/latex], год [latex]9[/latex] и так далее, состоит из [latex]10[/latex] больших месяцев и ни одного малого.»
Много времени прошло со дня введения календаря, и для празднования дня тысячелетия [latex]([/latex]год [latex]1000[/latex], месяц [latex]1[/latex], день [latex]1[/latex][latex])[/latex] решено было организовать королевскую лотерею, победителями которой станут те, кто прожил столько же дней, какое число выпадет в лотерее. Напишите программу, которая поможет людям вычислить количество дней от их дня рождения до дня тысячелетия.
Входные данные
Входные данные имеют следующий формат:
n
Y1 M1 D1
Y2 M2 D2
…
Yn Mn Dn
Первая строка задает количество тестов [latex]n, \left ( n \leq 100 \right )[/latex]. Далее следуют n тестов, каждый из которых представляет собой одну строку с тремя натуральными числами [latex]Y_{i}\left ( Y_{i}< 1000 \right ), M_{i} \left ( M_{i}< 10 \right )[/latex] и [latex]D_{i} \left ( D_{i}\leq 20 \right )[/latex], задающих соответственно год, месяц и день рождения некоторого человека в нотации королевского календаря.
Выходные данные
Для каждой даты рождения следует вывести в отдельной строке количество дней, прошедших со дня рождения (включительно) до дня тысячелетия (не включительно).
Тесты
№ | Ввод | Вывод |
1 | 2 1 1 1 344 3 1 |
196470 128976 |
2 | 3 696 5 1 182 9 5 998 8 7 |
59710 160715 252 |
3 | 2 344 2 19 696 4 19 |
128977 59712 |
4 | 1 999 10 20 |
1 |
Код
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> using namespace std; int main() { short n; int Y, M, D, daysAmount; const int bigMonth = 20, smallMonth = 19, bigYear = 200, smallYear = 195; cin >> n; for(int i = 0; i < n; i++) { daysAmount = 0; cin >> Y >> M >> D; if(Y % 3 == 0) daysAmount += (10 - M) * 20 + (20 - D); else{ if(M % 2 == 0) daysAmount += (smallMonth - D); else daysAmount += (bigMonth - D); for(int month = (M + 1); month <= 10; month++) { if(month % 2 == 0) daysAmount += smallMonth; else daysAmount += bigMonth; } } for(int year = (Y + 1); year < 1000; year++) { if((year % 3) == 0) daysAmount += bigYear; else daysAmount += smallYear; } cout << daysAmount + 1 << endl; } return 0; } |
Решение
Запишем большой месяц (20 дней) и малый месяц (19 дней) соответственно в константы bigMonth и smallMonth, а также большой год (200 дней) и малый год (195 дней) соответственно в bigYear и smallYear. Затем проходим по циклу for n раз. Проверяем, если год, в котором родился человек, кратен 3, считаем количество полных прожитых человеком месяцев (каждый месяц — 30 дней) первого после рождения года, а также дни месяца, в котором он родился. В противном случае ( else) прибавляем дни каждого полного месяца, проверяя, большой он, и малый. Затем добавляем дни первого прожитого человеком месяца, так же учитывая его длительность. После этого проходим по циклу for, начальной итерацией которого является ( Y + 1), потому что дни года рождения мы посчитали ранее. За каждый год, номер которого кратен 3, добавляем 200 дней, а за некратный — 195. В конце выводим количество полученных дней +1, так как должны посчитать их количество включительно с днем рождения.
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 |
#include <iostream> using namespace std; int main() { short n; int Y, M, D, daysAmount, multipleThree, notMultipleThree, lifeYears; const int bigMonth = 20, smallMonth = 19, bigYear = 200, smallYear = 195; cin >> n; for(int i = 0; i < n; i++) { daysAmount = 0; cin >> Y >> M >> D; lifeYears = 1000 - (Y + 1); if(lifeYears < 3 && lifeYears > 0) multipleThree = 1; else multipleThree = lifeYears / 3; if(lifeYears > 3 && lifeYears % 3 != 0)daysAmount += 5; notMultipleThree = lifeYears - multipleThree; daysAmount += multipleThree * bigYear + notMultipleThree * smallYear; if(Y % 3 == 0) { daysAmount += (10 - M) * bigMonth; daysAmount += bigMonth - D; } else { if(M % 2 != 0) { daysAmount += ( (10 - (M + 1)) / 2 ) * (bigMonth + smallMonth) + smallMonth; daysAmount += (bigMonth - D); } else { daysAmount += ( (10 - M) / 2 ) * (bigMonth + smallMonth); daysAmount += (smallMonth - D); } } cout << daysAmount + 1<< endl; } return 0; } |
Решение
Снова проходим по циклу for n раз. Однако, теперь считаем дни без помощи циклов. В переменную lifeYears записываем годы жизни -1 , так как дни года рождения мы посчитаем далее. Затем, в if проверяем, находится ли количество прожитых лет в диапазоне от 1 до 3. Если да, то в переменную multipleThree записываем 1 — количество лет, кратных трем, то есть 999 год. В else multipleThree приравниваем к lifeYears, деленую на 3. В следующем if проверяем, больше ли количество лет трех. Если да, прибавляем 5 дней за больший 999 год. Затем, в переменную notMultipleThree записываем количество лет, не кратных трем. В следующей строке прибавляем ко дням жизни годы, умноженные на соответствующие им количества в каждом. После, в if проверяем, кратен ли год рождения 3. Если да, Находим количество полных прожитых месяцев, и умножаем его на bigMonth. Далее, находим дни, прожитые в месяц рождения. В else проверяем, родился ли человек в нечетном месяце. Если да, добавляем к дням количество дней, вычисляющееся по формуле, записанной в коде, если нет — аналогично. В конце, выводим количество дней +1, так как должны посчитать их количество включительно с днем рождения.
Никита, добрый вечер. Вы, как и большинство людей, публикующих задачу на сайт впервые, допустили «ошибку новичка»: оформили формулы не в latex, а в теге strong.
Кроме этого, вы поместили свою работу в раздел «линейные вычисления», несмотря на то, что она очевидно к задачам на оные не принадлежит. Это также стоит исправить.
Благодарю вас за комментарий, Николь. Я исправил все недочеты, на которые вы мне указали
Никита, все числа в условии также должны быть оформлены в latex, а не в теге strong.
Исправил
Никита, пару недочётов с отступами в коде подправьте пожалуйста. Если у вас Tab это 4 отступа, то пусть так будет везде
Исправил
Я зачту эту работу за циклы, если Вы пообещаете подумать как сделать без них.
Жаль никто не предложил в комментариях варианта как это сделать.
А вот у Рудницкого есть такой комментарий. Единственный пока из всех. Надо это как-то оценить…
Конечно. Я постараюсь решить ее иным способом
Замечательно.
А на проверку зачем поставили?
Будете переделывать, этот код и пояснение тоже оставьте.
Намекну. Общая идея решения без циклов — свести все к однородной по числу дней ситуации.
Если я правильно понял, что 4 года являются полным циклом? Значит с точностью до 4 лет можно получить ответ простым делением возраста в полных годах на 4 и умножением на (3*195+200)? Дальше нужно выделять такие области однородности пока не получим ответ.
Кстати! Вам не кажется, что мудрый король отмечает тысячелетие рановато?
Исправил
Никита, я зачту эту работу. Но так делать нельзя.
Вы не описываете алгоритм, а пересказываете код на русском языке. Вы полагаете читателя идиотом, который не понимает, что делает присваивание?
Вы пишите «В else multipleThree приравниваем к lifeYears, деленную на 3».
И что? Это было непонятно из кода?
А зачем Вы это сделали?
Почему эти волшебные манипуляции должны привести к решению?
Давайте на будущее описывать именно алгоритм.