A - Calendar Game HDU - 1079 (博弈+dfs)
题目链接:
A - Calendar Game
题目大意:给你一个1900.1.1 ~ 2001.11.4 之间的日期,然后每一次你有两种操作,一个是日期加一,一个是月份加一,你是先手,问你是否必胜。
具体思路:
模板:
1 int dfs(/*当前状态*/) {
2 if(/*当前状态已知为必胜/败态*/) {
3 return true; / return false;
4 }
5 if(mp[/*当前状态*/] != -1) {
6 return mp[/*当前状态*/];
7 }
8 for(/*遍历所有后继状态*/) {
9 if(dfs(/*后继状态*/) == 0) {
10 mp[/*当前状态*/] = 1;
11 return 1;
12 }
13 }
14 mp[/*当前状态*/] = 0;
15 return 0;
16 }
具体代码:
1 #include<bits/stdc++.h>
2 using namespace std;
3 # define ll long long
4 const int maxn = 2e5+100;
5 int dp[2210][13][34];
6 int f[30]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
7 bool isleap(int y)
8 {
9 if(y%400==0|| (y%100!=0&&y%4==0))
10 return true;
11 return false;
12 }
13 bool ok(int y,int m,int d)
14 {
15 if(isleap(y)&&m==2)
16 {
17 if(d<=29)
18 return true;
19 return false;
20 }
21 if(d<=f[m])
22 return true;
23 return false;
24 }
25 int solve(int y,int m,int d)
26 {
27 //cout<<y<<" "<<m<<endl;
28 if(y==2001&&m==11&&d==4)
29 return dp[y][m][d]=0;
30 if(y>2001)
31 return dp[y][m][d]=1;
32 if(y==2001&&m>11)
33 return dp[y][m][d]=1;
34 if(y==2001&&m==11&&d>4)
35 return dp[y][m][d]=1;
36 if(dp[y][m][d]!=-1)
37 return dp[y][m][d];
38 int ty,tm,td;
39 ty=y,tm=m,td=d;
40 if(isleap(ty)&&tm==2)
41 {
42 td++;
43 if(td==30)
44 td=1,tm++;
45 }
46 else
47 {
48 td++;
49 if(td>f[tm])
50 {
51 td=1;
52 tm++;
53 if(tm>12)
54 ty++,tm=1;
55 }
56 }
57 if(solve(ty,tm,td)==0)
58 {
59 return dp[y][m][d]=1;
60 }
61 ty=y,tm=m,td=d;
62 tm++;
63 if(tm>12)
64 ty++,tm=1;
65 if(ok(ty,tm,td)&&solve(ty,tm,td)==0)
66 return dp[y][m][d]=1;
67 return dp[y][m][d]=0;
68 }
69 int main()
70 {
71 int T;
72 scanf("%d",&T);
73 memset(dp,-1,sizeof(dp));
74 int y,m,d;
75 while(T--)
76 {
77 scanf("%d %d %d",&y,&m,&d);
78 if(solve(y,m,d))
79 printf("YES\n");
80 else
81 printf("NO\n");
82 }
83 return 0;
84 }