SRM 583 Div2 Medium IDNumberVerification

問題

問題文が長いので割愛.簡単に言うと18桁の数字と,各範囲ごとに(6, 8, 3, 1)どういう値になるのかを知らされている.与えられた数字が定義通りになっているのかどうかを判定する.

解答

やるだけ.何も工夫はいらない.月日の判定がやや面倒くさい.
# 本番ではうるう年判定をミスしてシステムテスト通らなかったのは内緒

inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}

class IDNumberVerification
{
public:
  string verify(string id, vector <string> regionCodes)
    {
      int n = id.size();
      string INVA = "Invalid";
      if (n!=18) return INVA;
      int i;
      //region
      cout << "region" << endl;
      string region = id.substr(0, 6);
      bool invalid = true;
      for(i = 0; i < regionCodes.size(); i++){
        if (region == regionCodes[i]){
          invalid = false;
          break;
        }
      }
      if (invalid) return INVA;

      // birthday
      cout << "birthday" << endl;
      int year = toInt(id.substr(6, 4));
      int month = toInt(id.substr(10,2));
      int day = toInt(id.substr(12,2));
      if (year < 1900 || 2011 < year) return INVA;
      if (month < 1 || 12 < month) return INVA;
      if (day < 1 || 31 < day) return INVA;
      if ((month == 4 && 30 < day) || (month == 6 && 30 < day) ||
          (month == 9 && 30 < day) || (month == 11 && 30 < day)) return INVA;
      if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)){
        if (month == 2 && 29 < day ) return INVA;
      }else if(month == 2 && 28 < day ) return INVA;

      // gender
      cout << "gender" << endl;
      int gender = toInt(id.substr(14, 3));
      if (gender == 0) return INVA;

      // checksum
      cout << "checksum" << endl;
      int check = 0;
      // long long test = 0;
      for(i = 0; i < n-1; i++){
        check = ((check+(id[i]-'0'))*2) % 11;
      }
      if (id[n-1] == 'X') check = (check+ 10)%11;
      else check = (check + id[n-1]-'0')%11;
      cout << "check = " << check << endl;
      if (check != 1) return INVA;
      if (gender %2 == 1) return "Male";
      return "Female";
    }
};