[POJ2488]A Knight's Journey

题目描述 Description

Background 
The knight is getting bored of seeing the same black and white squares again and again and has decided to make a journey 
around the world. Whenever a knight moves, it is two squares in one direction and one square perpendicular to this. The world of a knight is the chessboard he is living on. Our knight lives on a chessboard that has a smaller area than a regular 8 * 8 board, but it is still rectangular. Can you help this adventurous knight to make travel plans? 

Problem 
Find a path such that the knight visits every square once. The knight can start and end on any square of the board.

输入描述 Input Description

The input begins with a positive integer n in the first line. The following lines contain n test cases. Each test case consists of a single line with two positive integers p and q, such that 1 <= p * q <= 26. This represents a p * q chessboard, where p describes how many different square numbers 1, . . . , p exist, q describes how many different square letters exist. These are the first q letters of the Latin alphabet: A, . . .

输出描述 Output Description

The output for every scenario begins with a line containing "Scenario #i:", where i is the number of the scenario starting at 1. Then print a single line containing the lexicographically first path that visits all squares of the chessboard with knight moves followed by an empty line. The path should be given on a single line by concatenating the names of the visited squares. Each square name consists of a capital letter followed by a number. 
If no such path exist, you should output impossible on a single line.

样例输入 Sample Input

3
1 1
2 3
4 3

样例输出 Sample Output

Scenario #1:
A1
 
Scenario #2:
impossible
 
Scenario #3:
A1B3C1A2B4C2A3B1C3A4B2C4

数据范围及提示 Data Size & Hint

 

之前的一些废话:是时候准备会考了。。

题解:完全的无脑大暴搜,注意是要字典序最小,所以我们循环的时候严格按照字典序最小搜索即可。

代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
#define mem(a,b) memset(a,b,sizeof(a))
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int T,n,m,dy[8]={-1,1,-2,2,-2,2,-1,1},dx[8]={-2,-2,-1,-1,1,1,2,2};
PII next[30][30];
bool a[30][30],ok;
bool judge(int x,int y){return x>=1 && x<=n && y>=1 && y<=m;}
bool check(){for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(!a[i][j])return 0;return 1;}
void print(int i,int j){printf("%c%d",i+'A'-1,j);}
void dfs(PII now)
{
    if(ok)return;
    if(check())
    {
        for(PII i=make_pair(1,1);i!=make_pair(0,0);i=next[i.first][i.second])print(i.first,i.second);
        ok=1;
        return;
    }
    int x=now.first,y=now.second;
    for(int i=0;i<8;i++)
        if(!ok && judge(x+dx[i],y+dy[i]) && !a[x+dx[i]][y+dy[i]])
        {
            a[x+dx[i]][y+dy[i]]=1;
            next[x][y]=make_pair(x+dx[i],y+dy[i]);
            dfs(make_pair(x+dx[i],y+dy[i]));
            if(!ok)next[x][y]=make_pair(0,0);
            if(!ok)a[x+dx[i]][y+dy[i]]=0;
        }
}
int main()
{
    T=read();
    for(int Case=1;Case<=T;Case++)
    {
        printf("Scenario #%d:
",Case);
        m=read();n=read();
        a[1][1]=1;dfs(make_pair(1,1));
        if(!ok)printf("impossible");
        printf("

");
        mem(next,0);mem(a,0);ok=0;
    }
    return 0;
}
View Code

总结:OI中由于输入问题x,y都是反着的,一定要注意。