問題
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;
}
};
#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;
}
};