题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1079
思路:条件只有2001.11.4选择的人输,考虑11.3选的人赢,11.2输,逆序模拟一下必胜点和必败点即可。如果两种选择中能选到必败点,则这个点为必胜点。若选不到则这个点为必败点。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int sg[2002][14][35];
int m[13]={0,31,0,31,30,31,30,31,31,30,31,30,31};
int leap(int x)
{
if(x%4!=0) return 0;
if(x%400==0) return 1;
if(x%100==0) return 0;
return 1;
}
void preinit()
{
memset(sg,0,sizeof(sg));
}
void runsg(int yy,int mm,int dd)
{
int res,ty=yy,tm=mm,td=dd;
if(mm==12) res=sg[yy+1][1][dd];
else res=sg[yy][mm+1][dd];
if(leap(yy)) m[2]=29;
else m[2]=28;
td++;
if(td>m[tm]) td=1,tm++;
if(tm>12) ty++,tm=1,td=1;
res+=sg[ty][tm][td];
if(res==0) sg[yy][mm][dd]=1;
else sg[yy][mm][dd]=0;
return ;
}
void rundate()
{
sg[2001][11][4]=1;
int year=2001,month=11,day=4;
while(1)
{
if(year==1900&&month==1&&day==1) break;
if(leap(year)) m[2]=29;
else m[2]=28;
day--;
if(day==0) month--,day=m[month];
if(month==0) year--,month=12,day=31;
runsg(year,month,day);
}
}
int main()
{
preinit();
rundate();
int t,a,b,c;
cin>>t;
while(t--)
{
cin>>a>>b>>c;
if(sg[a][b][c]==1) printf("NO\n");
else printf("YES\n");
}
return 0;
}
本文提供了一道来自杭州电子科技大学OJ(HDU OJ)的题目1079的解题思路及代码实现。通过逆序模拟的方式确定游戏中的必胜点和必败点,最终判断玩家是否能够赢得游戏。
315

被折叠的 条评论
为什么被折叠?



