ZOJ1008 Gnome Tetravex

本文探讨了如何通过深度优先搜索(DFS)算法解决Gnome Tetravex问题,该问题涉及将相同形状的方块进行合理放置。文章详细介绍了剪枝技巧、方块聚合及验证过程,确保所有可能的解决方案被有效排除或验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

比较简单的DFS题,不要给它吓到了。

需要剪枝,比较简单,把相同的方块聚合起来,如果一块方块不能放于某个位置,则和它相同的方块也不能放在这个位置。


/*******************************************************************************
 # Author : Neo Fung
 # Email : neosfung@gmail.com
 # Last modified: 2012-04-17 19:26
 # Filename: ZOJ1008 Gnome Tetravex.cpp
 # Description : 
 ******************************************************************************/
#ifdef _MSC_VER
#define DEBUG
#define _CRT_SECURE_NO_DEPRECATE
#endif

#include <fstream>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>
#include <limits.h>
#include <algorithm>
#include <math.h>
#include <numeric>
#include <functional>
#include <ctype.h>
#define MAX 100
using namespace std;

struct NODE
{
	int top,right,buttom,left;
	bool operator== (const NODE &tmp)
	{
		return top==tmp.top && right==tmp.right && buttom==tmp.buttom && left==tmp.left;
	}
}node[MAX];

int map[MAX][MAX],visit[MAX];
int sum[MAX];
bool ans;
void dfs(int p,const int &n)
{
	if(p==n*n || ans )
  {
    ans=true;
		return;
  }
	int x=p/n,y=p%n;
	for(int i=0;i<n*n && !ans;++i)
		if(sum[i])
		{
			if(x>0)
				if(node[i].top!=node[map[x-1][y]].buttom)
					continue;
			if(y>0)
				if(node[i].left!=node[map[x][y-1]].right)
					continue;
			map[x][y]=i;
			--sum[i];
			dfs(p+1,n);
			++sum[i];
		}
}

int main(void)
{
#ifdef DEBUG  
  freopen("../stdin.txt","r",stdin);
  freopen("../stdout.txt","w",stdout); 
#endif  

  int n,ncases=1;;
  //   scanf("%d",&ncase);

  while(scanf("%d",&n) && n)
  {
		if(ncases>1)
      printf("\n");
		memset(sum,0,sizeof(sum));
		for(int i=0;i<n*n;++i)
		{
      scanf("%d%d%d%d",&node[i].top,&node[i].left,&node[i].buttom,&node[i].right);
			bool flag=false;
			for(int j=0;j<i;++j)
				if(sum[j] && node[j]==node[i])
				{
					++sum[j];
					flag=true;
					break;
				}
			if(!flag)
				++sum[i];
		}
		memset(map,0,sizeof(map));
		ans=false;
		dfs(0,n);
    printf("Game %d: ",ncases++);
		if(ans)
			printf("Possible\n");
		else
			printf("Impossible\n");
  }

  return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值