不知怎么的,提交时老提示“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