深搜_Poj_2488(字典序)

//題目大意是讓騎士走遍棋盤裏的所有位置,不重複走同一格。
//題目主要陷阱體現在要求若輸出有多種,則輸出所有可能中字典序最小的那個。
//這裏的字典序主要體現在走的方向上哪個優先。因爲橫向是字母,縱向是數字,所以首先橫向上要儘量小,橫向相同時縱向要儘量小。
//此題走步優先順序在此給出: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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章