SRM 333 DIV1 Easy - BirthNumbersValidator (復習×○)

問題


http://community.topcoder.com/stat?c=problem_statement&pm=7291&rd=10657

誕生日を表わす10桁の数字が与えられる。

その数字を"YYMMDDCCCC"とすると、以下で表わされる。

YYが1907~2006までの西暦の下2桁。
うるう年も存在する。うるう年は400で割れるか、4で割れて100で割れない年。

MMが月であり、MMは女性の場合に限り51~62の範囲になる。

DDが日付。

CCCCはチェックサムで、10ケタの数字を11で割った余りが0になるようになっている。

このとき、与えられた数字が有効であればYESを、無効な数字であればNOを返す。

解き方


シミュレーション問題なので以下にシンプルに解くか。

今回の実装のポイントは3つ。
・各条件の判定には関数を用いる
・月の判定には配列を用いる。
・YES,NOの判定にはbool値を定義し、andを取って判定する。

コード


#define all(c) (c).begin(),(c).end()
#define FORE(i,d,e) for(int i=d;i<e;i++)
#define FOR(i,s,e) for (int i = int(s); i != int(e); i++)
#define FORIT(i,c) for (typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define ISEQ(c) (c).begin(), (c).end()

class BirthNumbersValidator {

public:

long long calc(string str){
stringstream out(str);
long long num;
out>>num;
return num;
}

bool isyear(int y){
return y==0||(y%4==0&&y%100!=0) ? true : false;
}

int ismonth(int m){
if(1<=m&&m<=12)return m;
if(51<=m&&m<=62)return m-50;
return -1;
}

bool isday(int m,int d,bool uruu){
if(d<1)return false;

int month[]={31,28,31,30,31,30,31,31,30,31,30,31};
if(m==2&&uruu){
if(d<=month[m-1]+1)return true;
else return false;
}
else if(d<=month[m-1])return true;
return false;
}

vector<string> validate(vector<string> test) {
vector<string> ans;

FORE(i,0,test.size()){
bool valid=true;

int day=calc(test[i].substr(4,2));
bool uruu=isyear(calc(test[i].substr(0,2)));
int month=ismonth(calc(test[i].substr(2,2)));

valid&=month!=-1;
valid&=isday(month,day,uruu);
valid&=calc(test[i])%11==0;

if(valid)ans.push_back("YES");
else ans.push_back("NO");

}

return ans;
}

};
このエントリーをはてなブックマークに追加