棋子移动——解题报告

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/JetRichardLee1/article/details/52301247
BFS
因为数轴无现长,并且有第一种操作:直接+4,或者-4,所以我们只用关心一开始有多少个棋子%4=0,1,2,3即可。
第二种操作:相当于是把两个棋子的位置各+1 %4。
第三种操作:相当于是把第i种棋子个数-1,第i+1种棋子个数-1,第i+2种棋子个数+1,。

然后BFS就行了,状态是f[31][31][31][31]。

#include <cstdio>
#include <cstring>
char a[31],b[31];
int g[4],h[4],e[4],d[810001][4],t,w,i,j,f[30][30][30][30],cas;
int x,y;

void get()
{
	int i;
	for (i=0;i<4;i++) e[i]=d[t][i];
}

void make()
{
	int i;
	if (f[e[0]][e[1]][e[2]][e[3]]==0) 
	{
		w++;
		for (i=0;i<4;i++) d[w][i]=e[i];
		f[e[0]][e[1]][e[2]][e[3]]=1;
	}
}

int main()
{
	freopen("move.in","r",stdin);
	freopen("move.out","w",stdout);
	scanf("%d\n",&cas);
	while (cas>0)
	{
		cas--;
		scanf("\n%s%s",a,b);
		memset(f,0,sizeof(f));
		memset(g,0,sizeof(g));
		memset(h,0,sizeof(h));
		x=0;
		for (i=0;i<30;i++) 
			if (a[i]=='*')
			{	
				x++;
				g[i%4]++;
			}
		y=0;
		for (i=0;i<30;i++)
			if (b[i]=='*')
			{
				y++;
				h[i%4]++;
			}
		if (x>=y)
		{
			t=0;
			w=0;
			for (i=0;i<4;i++)
				e[i]=g[i];
			make();
			do
			{
				t++;
				for (i=0;i<4;i++)
				{
					get();
					if ((e[i]>0)&&(e[(i+1)%4]>0))
					{
						e[i]--;
						e[(i+1)%4]--;
						e[(i+2)%4]++;
						make();
					}
					get();
					if ((e[i]>0)&&(e[(i+2)%4]>0))
					{
						e[i]--;
						e[(i+1)%4]++;
						e[(i+2)%4]--;
						e[(i+3)%4]++;
						make();
					}
				}
			}
			while (t<w);
		}
		if (f[h[0]][h[1]][h[2]][h[3]]==1) printf("%s\n","YES");
		else printf("%s\n","NO");
	}
}


没有更多推荐了,返回首页