题意:给出一个n×m的地图,第0行和第0列是一条神奇的河。在这个世界中,每过半天,人就会变成猪,猪就会变成人,跳到河里前,如果是猪,那么就会变成人,然后不会变回猪了,否则只能永远变成猪~无论对于猪和人来说,如果当前的位置是(x,y),那么下一次可以跳到( x - k * y , y ) 或( x , y - k * x ),k是一个正整数。每跳一次就会过半天,由于人是有智慧的,他可以选择自己怎么跳,但猪非常蠢,只会随机跳,问最开始在每个位置,是猪还是人才能保证最后一定会变成人。
思路:这题最开始读了好久没读懂,开始还以为是gcd乱搞,果断wa了,后来yy了样例才才出题意。其实知道了题意就好做了~如果x==y,那么下一次一定会跳到河里,这时状态一定是猪才行,如果x%y==0||y%x==0,那么这时要是人,因为此时一定可以找到一个x==y的点跳过去,否则的话,就要去枚举一下了,如果某个点的后继所有状态中,都是人,那么这个位置的状态就是猪了,否则就是人,此时人可以选一个状态为猪的位置跳过去~
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn=40000+10;
char res[maxn];
int n,m;
inline int getp(int x,int y) { return (x-1)*m+y-1;}
char cal(int x,int y)
{
if(x==y) return res[getp(x,y)]='P';
if(x%y==0||y%x==0) return res[getp(x,y)]='H';
if(x>y)
{
for(int i=1;x-y*i>0;i++)
if(res[getp(x-i*y,y)]=='P') return res[getp(x,y)]='H';
}
else
{
for(int i=1;y-x*i>0;i++)
if(res[getp(x,y-x*i)]=='P') return res[getp(x,y)]='H';
}
return res[getp(x,y)]='P';
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int tcase=0;
while(~scanf("%d%d",&n,&m))
{
printf("Case #%d:\n",++tcase);
for(int i=1;i<=n;++i)
{
for(int j=1;j<=m;++j)
printf("%c",cal(i,j));
printf("\n");
}
}
return 0;
}