Zoj 1024 Calendar Game
タイトルのソース:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=24
アナログ
勝利した方は2001年11月4日を倒さなければなりません。以下は推論の結果を観察します。11月4日、11+4=15は奇数です。一日プラスしても一ヶ月プラスしてもm+dのパリティは変わります。以下の特例を除いて2月28日と9月30日と11月30日です。mとdがこの3日間なら先駆者必勝です。2月28日から3月28日まで9月30日から10月1日までの11月30日から12月1日までの残りはm+dが偶数の場合のみ先勝します。他に特別な状況はありません。
アナログ
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int IsWin[102][13][32];// 1 ,0 , -1
int Month_Day[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int Judge(int y, int m, int d)
{
if(y > 101 || (y == 101 && (m > 11 || (m == 11 && d > 4))))
return 1;
if(y == 101 && m == 11 && d == 4)
return 0;
if(IsWin[y][m][d] == -1)
{
int win = 0;
if(m != 12)
{
if(d <= Month_Day[m] || (d == 29 && m == 1 && (((y % 4 == 0) && (y % 100)) || (y % 400 == 0)) && y != 0))
if(Judge(y, m+1, d) == 0)
win = 1;
}
else if(Judge(y+1, 1, d) == 0)
win = 1;
if(win == 0)
{
if(d < Month_Day[m])
win = 1 - Judge(y, m, d+1);
else if(m != 12)
win = 1 - Judge(y, m+1, 1);
else
win = 1- Judge(y+1, 1, 1);
}
IsWin[y][m][d] = win;
}
return IsWin[y][m][d];
}
int main()
{
int T;
cin>>T;
int y, d, m;
while(T--)
{
memset(IsWin, 0xff, sizeof(IsWin));
scanf("%d %d %d", &y, &m, &d);
if(Judge(y-1900, m, d) == 1)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
ネット上にまだある思想は、彼をゲームと見なしています。勝利した方は2001年11月4日を倒さなければなりません。以下は推論の結果を観察します。11月4日、11+4=15は奇数です。一日プラスしても一ヶ月プラスしてもm+dのパリティは変わります。以下の特例を除いて2月28日と9月30日と11月30日です。mとdがこの3日間なら先駆者必勝です。2月28日から3月28日まで9月30日から10月1日までの11月30日から12月1日までの残りはm+dが偶数の場合のみ先勝します。他に特別な状況はありません。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int main()
{
int T;
int y, m, d;
cin>>T;
while(T--)
{
scanf("%d %d %d", &y, &m, &d);
if(m == 2 && d == 28)
{
printf("YES
");
continue ;
}
else if(m == 9 && d == 30)
{
printf("YES
");
continue ;
}
else if(m == 11 && d == 30)
{
printf("YES
");
continue ;
}
else if((m+d)%2 == 0)
{
printf("YES
");
continue ;
}
printf("NO
");
}
return 0;
}