Description
Input
Output
一道坑爹的搜索……题意是可以往任意方向移动3格,或者如果旁边有格子的时候可以越过它移动,然后把它吃掉。要求吃到最后一个的位置在x0,y0
注意到可以越三格移动……所以取棋盘左上的3*3的格子,可以证明无论棋盘上何处的格子都可以通过一次3格的移动走到3*3的格子里
然后就可以用一个3*3的数组保存棋盘的状态,然后因为总的格子数小,还可以用10^9的数保存棋盘的状态(注意要算出3*3的九宫格中每一格最多放多少个,不然会wa)
然后就可以dfs搞之
再加个记忆化更快(注意每组数据都要重新hash)
#include<cstdio> #include<cstring> #define mod 1000007 const int mx[8]={0,0,-1,1,-1,1,-1,1}; const int my[8]={1,-1,0,0,1,-1,-1,1}; struct hashing{ int test,next; bool ok; }hash[1000010]; int head[mod]; int cnt,tox,toy; int maxnum[4][4]; int a[4][4]; int K,N,M; inline int find(int now) { int s=now%mod; for (int i=head[s];i;i=hash[i].next) if (hash[i].test==now)return hash[i].ok; return -1; } inline void ins(int now,bool ok) { int s=now%mod; hash[++cnt].test=now; hash[cnt].ok=ok; hash[cnt].next=head[s]; head[s]=cnt; } inline bool ok() { for(int i=1;i<=9;i++) { int ny=i%3;if (!ny)ny=3;int nx=(i-1)/3+1; if (nx==tox&&ny==toy&&a[nx][ny]!=1)return 0; if (nx!=tox||ny!=toy)if(a[nx][ny]!=0)return 0; } return 1; } inline bool dfs() { int now=0; for (int i=1;i<=3;i++) for(int j=1;j<=3;j++) now=now*10+a[i][j]; int fnd=find(now);if (fnd!=-1)return fnd; for (int i=1;i<=3;i++) for (int j=1;j<=3;j++) if(a[i][j]) { for(int k=0;k<8;k++) { bool mrx=0,mry=0; int sx=i+mx[k];if (sx>3){sx-=3;mrx=1;}if (sx<1){sx+=3;mrx=1;} int sy=j+my[k];if (sy>3){sy-=3;mry=1;}if (sy<1){sy+=3;mry=1;} if (!a[sx][sy])continue; if ((mrx||mry)&&a[i][j]==maxnum[i][j])continue; int tx=i+2*mx[k];if (tx>3)tx-=3;if (tx<1)tx+=3; int ty=j+2*my[k];if (ty>3)ty-=3;if (ty<1)ty+=3; if (a[tx][ty]==maxnum[tx][ty])continue; a[i][j]--; a[sx][sy]--; a[tx][ty]++; if (dfs()) { ins(now,1); return 1; } a[i][j]++; a[sx][sy]++; a[tx][ty]--; } } ins(now,0); return 0; } int main() { freopen("galaxy.in","r",stdin); freopen("galaxy.out","w",stdout); while (scanf("%d%d%d%d%d",&K,&N,&M,&tox,&toy)!=EOF) { memset(hash,0,sizeof(hash)); memset(head,0,sizeof(head)); memset(a,0,sizeof(a)); cnt=0; tox=(tox-1)%3+1; toy=(toy-1)%3+1; int now=0; for (int i=1;i<=9;i++) { int xx=(i-1)/3+1; int yy=(i-1)%3+1; now*=10; if (xx==tox&&yy==toy)now++; } ins(now,1); for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) maxnum[i][j]=(N/3)*(M/3)+(N%3>=i)*(M/3)+(M%3>=j)*(N/3)+(N%3>=i&&M%3>=j); for (int i=1;i<=K;i++) { int x,y; scanf("%d%d",&x,&y); x=(x-1)%3+1; y=(y-1)%3+1; a[x][y]++; } bool mrkres=0; for (int i=1;i<=3;i++) for (int j=1;j<=3;j++) if (a[i][j]>maxnum[i][j])mrkres=1; if (mrkres) { printf("No\n"); continue; } if (dfs())printf("Yes\n"); else printf("No\n"); } }
——by zhber,转载请注明来源