您的位置:首页 > 其它

poj_2488_A Knight's Journey_骑士周游问题

2013-10-09 21:56 483 查看
实在是自己照着模板写一遍不喜欢书上的代码风格就用网上的搜的一份代码

说实话vector用的却是不顺溜

#include <iostream>
#include <stdio.h>
#define two(X) ((ULL)1<<(X))
using namespace std;
typedef unsigned long long ULL;
const int dx[]={2, 1, -1, -2, -2, -1, 1, 2};
const int dy[]={-1, -2, -2, -1, 1, 2, 2, 1};
ULL lim = two(63)-1 + two(63);
int cnt[8][8], NX, NY;
int sign=0;
vector<pair<int, int>>answ, ans;
bool dfs(int x, int y, ULL state){
if(state==lim){
answ.push_back(make_pair(x, y));
sign=1;
return 1;
}

int ct =0;
int px[9], py[9], id[9];
for(int i=0; i<8; i++){
int nx = x+dx[i];
int ny = y+dy[i];
if(bx>=0&&nx<NX&&y>=0&&y<NY && !(state&two(nx*NY+ny))){
px[ct]=nx; py[ct]=ny;
ct++;
}
}
if(!ct){
return 0;
}
for(int i=0; i<ct; i++)id[i]=i;
for(int i=0; i<ct; i++){
for(int j=i+1; h<ct; j++){
if(cnt[px[id[i]]][py[id[i]]] > cnt[px[id[j]]][py[id[j]]]){
swap(id[i], id[j]);
}
}
}
for(int i=0; i<ct; i++){
if(dfs(px[id[i]]), py[id[i]], state|two(px[id[i]]*NY+py[id[i]])){
answ.push_back(make_pair(x, y));
return 1;
}
}
return 0;
}
vector<pair<int ,int>>slove(int NX0, int NY0)
{
NX=NX0; Ny=NY0;
answ.claer();
lim=two(NX*NY-1)-1+two(NX*NY-1);
for(int i=0; i<8; i++){
for(int j=0; j<8; j++){
cnt[i][j]=0;
for(int k=0; k<8; k++){
int nx=i+dx[k];
int ny=j+dy[k];
if(nx>=0 && nx<NX &&ny>=0 && ny<NY){
cnt[i][j]++;
}
}
}
}
dfs(0, 0, 1);
return answ;
}
int main()
{
int t, n, m;
scanf("%d", &t);
for(int i=1; i<=t; i++){
sign=0;
scanf("%d%d", &n, &m);
ans=slove(n, m);
printf("Scenario #%d:\n", i);
if(sign){
for(int i=0; i<n*m; i++){
printf("%c", ans[i]+64);
}
}
else{
printf("impossible");
}
printf("\n");
}
}


#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAX 27
int dir[8][2]={{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};//下一步的八个方向
int step,zx[MAX],zy[MAX],map[MAX][MAX],mark;//记录已经走过的步数,记录走过的网格的横纵坐标,标记该网格是否走过,记录是否找到路径
int p,q;

int dfs(int i,int j)//深搜函数
{
if(mark)return 0;//如果已经找到路径 返回
int x,y;
zx[step]=i;//记录当前网格的横坐标
zy[step]=j;//记录当前网格的纵坐标
step++;
if(step==p*q)//如果走过的步数等于棋盘上网格的总数
{
mark=1;//找到路径
return 0;//返回
}
map[i][j]=1;//标记该网格
for(int k=0;k<8;k++)
{
x=i+dir[k][1];//下一步x
y=j+dir[k][0];//下一步y,这个地方的x,y的顺序千万别错了,为了保证字典续
if(map[x][y]==0&&x>0&&x<=p&&y>0&&y<=q)//判断是否走过 判断是否越界
{
dfs(x,y);//如果没有走过,没有越界,向下深搜
step--;//如果返回 步数减一
}
}
map[i][j]=0;//清除该网格的标记
return 0;
}

int main()
{
//freopen("input.txt","r",stdin);
//freopen("output1.txt","w",stdout);
int n;
while(cin>>n)
{
for(int i=1;i<=n;i++)
{
cin>>p>>q;
memset(map,0,sizeof(map));//数组清零
step=mark=0;
dfs(1,1);//从(1,1)号网格开始深搜
cout<<"Scenario #"<<i<<":"<<endl;
if(mark)
{
for(int j=0;j<p*q;j++)
printf("%c%d",zy[j]+'A'-1,zx[j]);
cout<<endl;
}
else cout<<"impossible"<<endl;
if(i!=n)cout<<endl;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: