poj2488 dfs

N - 搜索

Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

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

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

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 Outpu

Scenario #1: A1

Scenario #2: impossible

Scenario #3: A1B3C1A2B4C2A3B1C3A4B2C4
题目大意:就是给你一个棋盘,上面有一个knight,给你了他的移动规则,同时给你棋盘的大小,他可以从任意位置开始移动(此句有坑点),首先让你判断他能不能走完这个棋盘,即每个位置都能移动到,
若不能,输出“impossible",若可以,则输出其走过的路径(要求字典序最小!)。
思路分析:此题坑我甚苦,且听我娓娓道来,思路没问题,图比较小,深搜可以水过,首先是那个可以从任意位置,实际上,就应该从(0,0)位置开始,因为如果能够从其他位置完成遍历,则一定会经过(0,0)点,即从(0,0)点开始也一定可以
完成遍历,同时从(0,0)点开始遍历无疑是保证字典序最小的最好选择了吧,这个字典序还会坑你一次,在开方向数组的时候,要按照先y后x典序最小来开,因为最后输出的时候,字母位置加的是y坐标而不是X坐标,地图数组开大一些,貌似地图并没有题意 说的那么小,然后说下大体思路,深搜,三个参数:x,y,step。用step来判断是否结束dfs,同时开一个二维数组来储存每一步的位置,用flag来判断是否找到。

代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
using namespace std;
const int maxn=100;
int vis[maxn*maxn][2];
int p,q,step,flag;
char maps[maxn][maxn];
int f[8][2]={{-1,-2},{1,-2},{-2,-1},{2,-1},{-2,1},{2,1},{-1,2},{1,2}};
int ans=0;
int dis[maxn][maxn];
void dfs(int x,int y,int step)
{
    if(step==p*q&&flag==0)
    { cout<<"Scenario #"<<++ans<<":"<<endl;
        for(int i=0;i<p*q;i++)
        printf("%c%d",'A'+vis[i][1],vis[i][0]+1); flag=1;
        cout<<endl<<endl;
        return;
    }
    for(int i=0;i<8;i++)
    {
        int a=x+f[i][0];
        int b=y+f[i][1];
        if(a>=0&&a<p&&b>=0&&b<q&&!dis[a][b])
        {
            dis[a][b]=1;
            vis[step][0]=a;
            vis[step][1]=b;
            dfs(a,b,step+1); dis[a][b]=0;
            if(flag) return;
        }
    }
}
int main()
{
    int n;
    cin>>n;
  while(n--)
  {
        memset(dis,0,sizeof(dis));
        cin>>p>>q;
        flag=0;
        dis[0][0]=1;
        vis[0][0]=0,vis[0][1]=0;
         dfs(0,0,1);
        if(!flag)
        {
            cout<<"Scenario #"<<++ans<<":"<<endl;
cout<<"impossible"<<endl<<endl;

        }
  }
    return 0;
}
对了,这种题目一定要按题目要求的输出格式进行输出,本题就要求在输出个答案以后换行两次,一定要认真仔细。
加油!

原文地址:https://www.cnblogs.com/xuejianye/p/5314259.html