这个题太坑爹了,题意也好纠结。
是这样的,给你一个n*m的矩形,中间有n*m个1*1的格子,有不同的跳跃方法。如果当前为human(人类)那么他可以有意识的选择自己下一步跳往何方;如果当前为pig(猪)那么它会沿着上一次跳跃的步奏跳跃。现在问你对于每一个格子,初始状态为那种(human OR pig)可以使得最后跳出整个矩形。
这样想,对于(1,1)的P显然可以一步就跳出去了。所以这是一个必胜态。
然后任何一个可以直接跳到(1,1)的格子都应该为H,不为H的格子一定就是P了,因为沿着上一次的方向跳一定可以跳到一个H去。
题目中我直接用的一个一维数字模拟二维数组,时间和空间上都十分可观,就是(T_T)调试出了好多小问题。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #define maxn 40040 5 using namespace std; 6 7 int n,m,k; 8 char s[maxn]; 9 10 int f(int x,int y) { return (x-1)*m+y; } 11 12 void update(int cur) 13 { 14 cur--; 15 for (int x=cur/m+1,y=cur%m+1+x; y<=m; y+=x) s[f(x,y)]='H'; 16 for (int y=cur%m+1,x=cur/m+1+y; x<=n; x+=y) s[f(x,y)]='H'; 17 } 18 19 int main() 20 { 21 int cas=0; 22 while (scanf("%d%d",&n,&m)!=EOF) 23 { 24 memset(s,0,sizeof s); 25 for (int i=1; i<=n*m; i++) 26 { 27 if (s[i]=='H') continue; 28 s[i]='P'; 29 update(i); 30 } 31 printf("Case #%d:\n",++cas); 32 for (int i=1; i<=n*m; i++) 33 { 34 printf("%c",s[i]); 35 if (i%m==0) printf("\n"); 36 } 37 } 38 return 0; 39 }