浙大ZOJ 1008 Gnome Tetravex问题解决

不知怎么的,提交时老提示“Time Limit Exceeded”,但是在我自己机器上,我用clock()测量了下时间,当n为最大值5的时候,才200ms左右,不知为什么提交后,会显示10001ms。不管了,把代码贴在这里吧。

一、工程代码及算法设计注释

--------------------------------------------------gnome_tetravex.h----------------------------------------------

#ifndef JLU_CCST_GNOME_TETRAVEX_H
#define JLU_CCST_GNOME_TETRAVEX_H

extern bool isGnomeTetravexSolvable(int k,int n);
extern void testIsGnomeTetravexSolvable();

#endif//JLU_CCST_GNOME_TETRAVEX_H

--------------------------------------------------gnome_tetravex.cpp ----------------------------------------------

/**
题目来源:浙大ACM在线测试——ZOJ,题目编号1008,题名"Gnome Tetravex"
URL:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1008
Author:hellogdc<gdcjlu@163.com>
Finish Time:2014.01.06
*/

/**
算法设计:
分析:整个矩阵的状态有 (n*n)! 个。但是穷举如此多的状态,并且对每个状态还得监测是否合法,
这样需要太多时间。所以,可以试着找出一个逐步生成如此多状态的方法。在生成的过程中,如果
发现没有办法进行下去,则对此进行剪枝,即往后就不用生成、检测了,这样可以缩减需要检测的状态
的数目。
设计:从矩阵左上角出发,向右进行扩展,每个将要扩展的元素需要满足与左边的元素及上边的元素匹配。
设算法为F(list,k,n)。
算法执行体:遍历list,找出一个元素,使其与矩阵第k个元素的左单元与上单元匹配。如果找到,则从list中
删除该元素,然后执行F(list,k+1,n),检查该函数是否返回true,如是,则函数返回,否则,恢复list,继续找。
如果遍历完list中所有元素,还没找到合适的,则说明无法成功生成,返回false。
递归出口:
1. k==n*n,则说明存在。
2. 遍历完list中所有元素,还是没找到合适的元素填充,则说明不存在。

注:本来是打算给list做删除、添加操作的,但是由于同时又有遍历操作,这样就不太合适,于是就用一个大数组,
来记录元素是否被使用。这样做的一个缺陷是:每次递归时,都得遍历n*n规模的list。
*/
#include <iostream>
#include <list>
#include <vector>
#include <ctime>
#include <cstdlib>
using namespace std;
struct GnomeTetravexUnit{
	int top,right,bottom,left;
};
static vector<GnomeTetravexUnit> gnomeTetravexList;
static vector<GnomeTetravexUnit> legalResult;
static vector<bool> isUsed;
bool isGnomeTetravexSolvable(int k,int n){
	if(k==n*n)
		return true;

	bool flag=false;
	for(int i=0;i<gnomeTetravexList.size();i++){
		if(isUsed[i])
			continue;
		if( ((k-n)<0||gnomeTetravexList[i].top==legalResult[k-n].bottom)&&//与上单元比较
			((k%n==0)||gnomeTetravexList[i].left==legalResult[k-1].right) ){//与左单元比较
				isUsed[i]=true;
				legalResult[k]=gnomeTetravexList[i];
				flag=isGnomeTetravexSolvable(k+1,n);
				isUsed[i]=false;//恢复
		}
		if(flag)
			break;
	}
	return flag;
}

void testIsGnomeTetravexSolvable(){
	bool flag=false;
	int n=2;
	int size;
	clock_t start,end;
	gnomeTetravexList.resize(n*n);
	legalResult.resize(n*n);
	GnomeTetravexUnit unit1={5,9,1,4};
	GnomeTetravexUnit unit2={4,4,5,6};
	GnomeTetravexUnit unit3={6,8,5,4};
	GnomeTetravexUnit unit4={0,4,4,3};
	gnomeTetravexList[0]=unit1;
	gnomeTetravexList[1]=unit2;
	gnomeTetravexList[2]=unit3;
	gnomeTetravexList[3]=unit4;
	isUsed.resize(n*n);
	for(int i=0;i<n*n;i++)
		isUsed[i]=false;
	cout<<"Original Matrix:"<<endl;
	for(int i=0;i<n*n;i++){
			cout<<gnomeTetravexList[i].top<<' '<<gnomeTetravexList[i].right<<' '
				<<gnomeTetravexList[i].bottom<<' '<<gnomeTetravexList[i].left<<endl;
		}
	start=clock();
	//flag=isGnomeTetravexSolvable(0,n);
	end=clock();
	cout<<"Consuming Time: "<<(end-start)<<endl;
	if(flag){
		cout<<"Possible"<<endl;
		cout<<"Result Matrix:"<<endl;
		for(int i=0;i<n*n;i++){
			cout<<legalResult[i].top<<' '<<legalResult[i].right<<' '<<legalResult[i].bottom<<' '<<legalResult[i].left<<endl;
		}
	}
	else
		cout<<"Impossible"<<endl;
	//
	n=2;
	size=n*n;
	gnomeTetravexList.clear();
	legalResult.clear();
	gnomeTetravexList.resize(size);
	legalResult.resize(size);
	isUsed.resize(size);
	GnomeTetravexUnit unit11={1,1,1,1};
	GnomeTetravexUnit unit22={2,2,2,2};
	GnomeTetravexUnit unit33={3,3,3,3};
	GnomeTetravexUnit unit44={4,4,4,4};
	gnomeTetravexList[0]=unit11;
	gnomeTetravexList[1]=unit22;
	gnomeTetravexList[2]=unit33;
	gnomeTetravexList[3]=unit44;
	for(int i=0;i<n*n;i++)
		isUsed[i]=false;
	cout<<"Original Matrix:"<<endl;
	for(int i=0;i<n*n;i++){
			cout<<gnomeTetravexList[i].top<<' '<<gnomeTetravexList[i].right<<' '
				<<gnomeTetravexList[i].bottom<<' '<<gnomeTetravexList[i].left<<endl;
		}
	start=clock();
	//flag=isGnomeTetravexSolvable(0,n);
	end=clock();
	cout<<"Consuming Time: "<<(end-start)<<endl;
	if(flag){
		cout<<"Possible"<<endl;
		cout<<"Result Matrix:"<<endl;
		for(int i=0;i<n*n;i++){
			cout<<legalResult[i].top<<' '<<legalResult[i].right<<' '<<legalResult[i].bottom<<' '<<legalResult[i].left<<endl;
		}
	}
	else
		cout<<"Impossible"<<endl;
	//
	n=4;
	size=n*n;
	gnomeTetravexList.clear();
	legalResult.clear();
	gnomeTetravexList.resize(size);
	legalResult.resize(size);
	isUsed.resize(size);
	GnomeTetravexUnit unit;
	for(int i=0;i<n*n;i++){
		isUsed[i]=false;
		unit.top=rand()%10;
		unit.right=rand()%10;
		unit.bottom=rand()%10;
		unit.left=rand()%10;
		gnomeTetravexList[i]=unit;
	}
	cout<<"Original Matrix:"<<endl;
	for(int i=0;i<n*n;i++){
			cout<<gnomeTetravexList[i].top<<' '<<gnomeTetravexList[i].right<<' '
				<<gnomeTetravexList[i].bottom<<' '<<gnomeTetravexList[i].left<<endl;
		}
	start=clock();
	flag=isGnomeTetravexSolvable(0,n);
	end=clock();
	cout<<"Consuming Time: "<<(end-start)<<endl;
	if(flag){
		cout<<"Possible"<<endl;
		cout<<"Result Matrix:"<<endl;
		for(int i=0;i<n*n;i++){
			cout<<legalResult[i].top<<' '<<legalResult[i].right<<' '<<legalResult[i].bottom<<' '<<legalResult[i].left<<endl;
		}
	}
	else
		cout<<"Impossible"<<endl;
}

-------------------------------------------------- main.cpp ----------------------------------------------

#if 1

#include "gnome_tetravex.h"
int main(){
	testIsGnomeTetravexSolvable();
	return 0;
}

#endif


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值