ZOJ1008 Gnome Tetravex(DFS)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1008

题意:

哈特近来一直在玩有趣的 Gnome Tetravex 游戏。在游戏开始时,玩家会得到 n×n(n≤5) 个正方形。每个正方形都被分成 4个标有数字的三角形(数字的范围是 0到9)。这四个三角形分 别被称为“左三角形”、“右三角形”、“上三角形”和“下三角形”。例如,图 2.12(a)是2×2的正 方形的一个初始状态。  


ZOJ1008 Gnome Tetravex(DFS)_第1张图片

图2.12 Gnome Tetravex游戏 玩家需要重排正方形,到达目标状态。在目标状态中,任何两个相邻正方形的相邻三角形上 的数字都相同。图 2.12(b)是一个目标状态的例子。 

判断是否有解。

题解:

DFS。一次确定每个格子填充什么样的方块。但是这样的话复杂度25!,TLE。为了能够减少时间,我们将相同类型的方块只保存一次,并且保存相同方块出现的次数。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX=6; 
struct  part
{
	int l,r,u,d;
	part(){};
	part(int u,int r,int d,int l):u(u),r(r),d(d),l(l){};
	bool operator ==(const part &tmp)
	{
		return tmp.l==l&&tmp.r==r&&tmp.u==u&&tmp.d==d;
	}
};
part p[MAX*MAX];//记录输入的块
int sum[MAX*MAX];//每种块的个数
int g[MAX][MAX];
int n;
bool ans;
void dfs(int t)
{
	if(t==n*n||ans) 
	{
		ans=true;
		return;
	}
	int x=t/n,y=t%n;
	for(int i=0;i<n*n&&!ans;i++)
	{
		if(sum[i])
		{
			if(x>0)
				if(p[i].u!=p[g[x-1][y]].d) continue;
			if(y>0)
				if(p[i].l!=p[g[x][y-1]].r) continue;
			g[x][y]=i;
			sum[i]--;
			dfs(t+1);
			sum[i]++;
		}
	}
}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int tcase=1;
	while(scanf("%d",&n)&&n)
	{
		if(tcase>1) printf("\n");
		printf("Game %d: ",tcase++);
		memset(sum,0,sizeof(sum));
		for(int i=0;i<n*n;i++)
		{
			int l,r,u,d;
			scanf("%d%d%d%d",&u,&r,&d,&l);
			p[i]=part(u,r,d,l);
			int flag=0;
			for(int j=0;j<i;j++)
			{
				if(p[j]==p[i])
				{
					flag=1;
					sum[j]++;
					break;
				}
			}
			if(!flag) 
				sum[i]++;
		}
		ans=false;
		dfs(0);
		printf("%s\n",ans?"Possible":"Impossible");
	}
	return 0;
}


你可能感兴趣的:(ZOJ1008 Gnome Tetravex(DFS))