POJ2488DFS

来源:互联网 发布:美利达淘宝旗舰店 编辑:程序博客网 时间:2024/06/04 19:35
A Knight's Journey
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 45494 Accepted: 15471

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

31 12 34 3

Sample Output

Scenario #1:A1Scenario #2:impossibleScenario #3:A1B3C1A2B4C2A3B1C3A4B2C4

Source

TUD Programming Contest 2005, Darmstadt, Germany

    题意:给出制定规格的网格,问马能不能不重复的全部走完,并按字典序输出路径。

    解题思路:这题显然用DFS会简单一些。开始的时候,我想的是:既然是要把所有的格子遍历一遍,而且输出的结果要以字典序的顺序输出,所以只需要调好搜索的顺序,并用数组存下路径即可。然后,经过我的多次调试,终于过了样例,以下是我的最初代码

#include <stdio.h>#include <memory.h>#include <string.h>#define maxn 30typedef struct road{    char p;    char q;} T;T arr[700];int flag[maxn][maxn],m,n,a=0;void dfs(int r,int s){    if(r<0||r>=m||s<0||s>=n) return;    if(flag[r][s]!=0) return;    flag[r][s]=1;    arr[a].p=s+'A';    arr[a].q=r+'1';    a++;    dfs(r+2,s+1);    dfs(r+2,s-1);    dfs(r-2,s-1);    dfs(r-2,s+1);    dfs(r+1,s+2);    dfs(r+1,s-2);    dfs(r-1,s+2);    dfs(r-1,s-2);}int main(){    //freopen("in.txt","r",stdin);    int t;    scanf("%d",&t);    for(int k=1; k<=t; k++)    {        a=0;        memset(flag,0,sizeof(flag));        scanf("%d%d",&m,&n);        printf("Scenario #%d:\n",k);        dfs(0,0);        int f=1;        for(int i=0; i<m; i++)            for(int j=0; j<n; j++)                if(flag[i][j]==0) f=0;        if(!f) printf("impossible\n");        else        {            for(int i=0; i<a; i++)                printf("%c%c",arr[i].p,arr[i].q);            printf("\n");        }    }    return 0;}

      结果不尽人意,果断被系统判了WA。debug调试一次后,我就明白了自己错在哪里。走到错误的路的时候,虽然搜索的进度会返回,但是flag已经标记,没有被改回来,所以后续搜索的时候会误以为此处已经在整条路径中。于是我就改用了回溯法。在走到错路的时候,返回时把flag还原回去,然后在dfs函数参数里加了路径的下标,这样保证每次存储的时候都是正确的路(就算前面存的是错误的回溯之后会重新赋值)。修改后,我的代码如下

#include <stdio.h>#include <memory.h>#include <string.h>#define maxn 30typedef struct road{    char p;    char q;} T;T arr[700];int flag[maxn][maxn],m,n,a=0,success=0,vis[2][8]= {{-2,-2,-1,-1,1,1,2,2},{-1,1,-2,2,-2,2,-1,1}};void dfs(int x,int y,int a){    if(success)  return;    arr[a].p=x+'A';    arr[a].q=y+'1';    if(a==m*n)    {        success=1;        return;    }    int yy,xx;    for(int i=0; i<8; i++)    {        xx=x+vis[0][i];        yy=y+vis[1][i];        if(flag[xx][yy]==1) continue;        if(yy<0||yy>=m||xx<0||xx>=n) continue;        flag[xx][yy]=1;        dfs(xx,yy,a+1);        flag[xx][yy]=0;    }}int main(){    //freopen("in.txt","r",stdin);    int t;    scanf("%d",&t);    for(int k=1; k<=t; k++)    {        a=0;        memset(flag,0,sizeof(flag));        scanf("%d%d",&m,&n);        printf("Scenario #%d:\n",k);        success=0;        flag[0][0]=1;        dfs(0,0,1);        if(!success) printf("impossible\n");        else        {            for(int i=1; i<=m*n; i++)                printf("%c%c",arr[i].p,arr[i].q);            printf("\n");        }        printf("\n");    }    return 0;}
    一次AC。

原创粉丝点击