Матч 333, Проверка дня рождения (BirthNumbersValidator)

Дивизион 2, Уровень 2

 

В Словакии каждому человеку присвоен 10 цифровой код, который описывает его дату рождения. Код имеет вид строки в формате “YYMMDDCCCC”, где

YY – последние две цифры года рождения;

Для мужчин MM обозначает номер месяца (от 01 до 12), для женщин номер месяца увеличен на 50 (от 51 до 62);

DD – дата рождения;

CCCC – произвольные цифры, являющиеся контрольной суммой. Эти цифры выбираются так, чтобы сумма всех 10 цифр делилась на 11.

Например, “8104121234” и “8154121239” представляют действительные коды. Строки “8134120005”, “8102310007” и “8104121235” кодами не являются.

По строке, содержащей 10 цифр, определить, является ли она кодом дня рождения (то есть является ли она корректной согласно выше описанным правилам). Считать, что год рождения может изменяться с 1907 до 2006. Високосным является год, который делится на 400, а также год, который делится на 4 и не делится на 100. В високосном году февраль содержит 29 дней.

 

Класс: BirthNumbersValidator

Метод: vector<string> validate(vector<string> test)

Ограничения: test содержит от 1 до 50 элементов, test[i] содержит 10 символов ‘0’ – ‘9’.

 

Вход. Массив строк.

 

Выход. Массив строк, i - ый элемент которого равен “YES” или “NO” в зависимости от того, является ли test[i] корректным кодом дня рождения.

 

Пример входа

test

{"8104121234"}

{"8102310007","8104121235"}

{"0411131237"}

 

Пример выхода

{"YES"}

{"NO", "NO"}

{"YES"}

 

 

РЕШЕНИЕ

элементарные вычисления

 

В ячейках days[i] храним максимальное число дней в  i - ом месяце (1 £ i £ 12). Функция getday(m, y) возвращает количество дней в месяце m и году y.

В 64-битовую целочисленную переменную s считываем входной код. Если он не делится на 11, то не является корректным. В переменные year, month, day занесем соответственно год, месяц и день рождения. Если их значения являются корректными, то и входная строка является корректным кодом дня рождения.

 

ПРОГРАММА

 

#include <cstdio>

#include <vector>

#include <string>

using namespace std;

 

int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

 

class BirthNumbersValidator

{

public:

  int getday(int m, int y)

  {

    if (m == 2 && (y % 4 == 0)) return 29;

    return days[m-1];

  }

 

  vector<string> validate(vector<string> test)

  {

    int i, year, month, day;

    long long s;

    vector<string> res(test.size(),"NO");

    for(i = 0; i <test.size(); i++)

    {

      s = atoi(test[i].substr(0,6).c_str()); s *= 10000;

      s += atoi(test[i].substr(6).c_str());

      if (s % 11 != 0) continue;

 

      year = 1900 + atoi(test[i].substr(0,2).c_str());

      if (year <= 1906) year += 100;

 

      month = atoi(test[i].substr(2,2).c_str());

      if (month >= 50) month -= 50;

      if ((month < 1) || (month > 12)) continue;

 

      day = atoi(test[i].substr(4,2).c_str());

      if ((day < 1) || (day > getday(month,year))) continue;

      res[i] = "YES";

    }

    return res;

  }

};