B
来源:互联网 发布:烟雾视频软件 编辑:程序博客网 时间:2024/04/30 03:14
大致题意:给出一个p行q列的国际棋盘,马可以从任意一个格子开始走,问马能否不重复的走完所有的棋盘。如果可以,输出按字典序排列最小的路径。打印路径时,列用大写字母表示(A表示第一列),行用阿拉伯数字表示(从1开始),先输出列,再输出行。
分析:如果马可以不重复的走完所有的棋盘,那么它一定可以走到A1这个格子。所以我们只需从A1这个格子开始搜索,就能保证字典序是小的;除了这个条件,我们还要控制好马每次移动的方向,控制方向时保证字典序最小(即按照下图中格子的序号搜索)。控制好这两个条件,直接从A1开始深搜就行了。
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <string>#include <map>#include <stack>#include <vector>#include <set>#include <queue>#define maxn 15#define MAXN 100005#define mod 1000000007#define INF 0x3f3f3f3f#define pi acos(-1.0)using namespace std;#define M 30int dx[8]={-1,1,-2,2,-2,2,-1,1};int dy[8]={-2,-2,-1,-1,1,1,2,2}; //8个方向bool map1[M][M]; //表示位置走没走过int cas,f,p,q;struct node //建立结构体来存储字母和数字{ int s; char s1;}pp[600];void print() //单独定义一个输出函数,比较方便{ cout<<"Scenario #"<<cas<<":"<<endl; for(int i=1;i<=p*q;i++) cout<<pp[i].s1<<pp[i].s; cout<<endl;}void go(int x,int y,int step) //搜索,字母,数字,以及是第几步{ pp[step].s=x; pp[step].s1='A'+y-1; if(step==p*q) { f=1; return ; } for(int j=0;j<8;j++) { if(x+dx[j]>0&&x+dx[j]<=p&&y+dy[j]>0&&y+dy[j]<=q&&map1[x+dx[j]][y+dy[j]]==false&&f==0) { map1[x+dx[j]][y+dy[j]]=true; go(x+dx[j],y+dy[j],step+1); map1[x+dx[j]][y+dy[j]]=false; //回溯 } }}int main(){ int t,n; cin>>t; cas=0; n=t; while(t--) { cas++; cin>>p>>q; pp[0].s='1'; pp[0].s1='A'; memset(map1,false,sizeof(map1)); f=0; map1[1][1]=true; go(1,1,1); if(f) print(); else { cout<<"Scenario #"<<cas<<":"<<endl; cout<<"impossible"<<endl; } if(cas!=n) cout<<endl;}}