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");
}
}