深搜_Poj_2488(字典序)

来源:互联网 发布:淘宝国产手机 编辑:程序博客网 时间:2024/06/05 12:01

//题目大意是让骑士走遍棋盘里的所有位置,不重复走同一格。
//题目主要陷阱体现在要求若输出有多种,则输出所有可能中字典序最小的那个。
//这里的字典序主要体现在走的方向上哪个优先。因为横向是字母,纵向是数字,所以首先横向上要尽量小,横向相同时纵向要尽量小。
//此题走步优先顺序在此给出:int go_x[8] = {-2,-2,-1,-1,1,1,2,2};int go_y[8] = {-1,1,-2,2,-2,2,-1,1};

#include<iostream>
#include<stack>
using namespace std;

 struct Node
{
bool has_been;
int x,y;
}node[8][8];

int n;//输入个数
int now_i;//当前第now_i个例子
int v,h;//纵、横
stack<Node> Q;//用来存储序列
stack<Node> W;//用来输出,即楼上的反方向。
bool all_ok;

//辅助变量
int i,j,l;

//走路的方向
int go_x[8] = {-2,-2,-1,-1,1,1,2,2};
int go_y[8] = {-1,1,-2,2,-2,2,-1,1};

//是否在棋盘内
bool IsIn(int x,int y)
{
if(x<0||x>=h||y<0||y>=v) return false;
else return true;
}

void dfs(int x,int y,int num)
{
Q.push(node[x][y]);//可以搜索到,先入栈
node[x][y].has_been = true;
if(num==v*h)//全部搜索成功
all_ok=true;
else
{
int i,tx,ty;
//走八个方向
for(i=0;i<8;i++)
{
tx=x+go_x[i];
ty=y+go_y[i];
if(IsIn(tx,ty) && !node[tx][ty].has_been)
dfs(tx,ty,num+1);
if(all_ok) return;
}
//没成功,恢复原来设置
node[x][y].has_been = false;
Q.pop();
}
}

int main()
{
while(cin>>n)
{
for(i=0;i<n;i++)//n个例子
{
if(i!=0) printf("\n");//如果不是第一行 先敲一回车
printf("Scenario #%d:\n",i+1);
//初始化
cin>>v>>h;
if(h>8||v>8)
{
printf("impossible\n");
continue;
}
for(j=0;j<h;j++)
{
for(l=0;l<v;l++)
{
node[j][l].x=j;
node[j][l].y=l;
node[j][l].has_been=false;
}
}
all_ok=false;
//dfs
for(j=0;j<h;j++)
{
for(l=0;l<v;l++)
{
dfs(j,l,1);
if(all_ok) break;
}
if(all_ok) break;
}
if(j==h) printf("impossible\n");
else
{
while(!Q.empty())
{
W.push(node[Q.top().x][Q.top().y]);
Q.pop();
}
while(!W.empty())
{
printf("%c%d",W.top().x+'A',W.top().y+1);
W.pop();
}
printf("\n");
}
}
}
return 0;
}