poj2488 A Knight's Journey裸dfs

A Knight's Journey
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 35868   Accepted: 12227

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 Output

Scenario #1:
A1

Scenario #2:
impossible

Scenario #3:
A1B3C1A2B4C2A3B1C3A4B2C4

Source

搞清楚一个字典序就行了,其余的很简单。

Posted by xijunlee93 at 2013-03-19 16:37:46 on Problem 2488
这一题的字典序:就是先按列排序,较小的在前。然后按行排序,也是较小的在前。
我的排序是这样的:
int diri[8]={-1,1,-2,2,-2,2,-1,1};
int dirj[8]={-2,-2,-1,-1,1,1,2,2};

 

大意很明了,就是找到一个路径让马走完所有的点,不重复不遗漏;思路很容易找到,直接用DFS搜索标记并回溯,一个点一个点作为起点去试;找到后停止;

#include<stdio.h>
 int dir[8][2]={-2,-1,-2,1,-1,-2,-1,2,1,-2,1,2,2,-1,2,1};   //记录方向
 int g,a,b;//g用来记录是否找到解,找到后不再搜索
 int vist[26][26],path[26][2];
 void find(int i,int j,int k)//i,j是要走的格子,k记录已经走过的步数
 {
     if(k==a*b)//走完了
     {
         for(int i=0;i<k;i++)
         printf("%c%d",path[i][0]+'A',path[i][1]+1);
         printf("\n");
         g=1;
     }
     else
     for(int x=0;x<8;x++)//8个方向依次搜索
     {
         int n=i+dir[x][0];
         int m=j+dir[x][1];
         if(n>=0&&n<b&&m>=0&&m<a&&!vist[n][m]&&!g)
         {
             vist[n][m]=1;//标记已走
             path[k][0]=n,path[k][1]=m;
             find(n,m,k+1);
             vist[n][m]=0;//清除标记
         }
     }
 }
 int main()
 {
     int n;
     scanf("%d",&n);
     for(int m=0;m<n;m++)
     {
         g=0;
         scanf("%d %d",&a,&b);
         for(int i=0;i<a;i++)//一个点一个点的尝试
             for(int j=0;j<b;j++)
                 vist[i][j]=0;
         vist[0][0]=1;
         path[0][0]=0,path[0][1]=0;
         printf("Scenario #%d:\n",m+1);
         find(0,0,1);
         if(!g) printf("impossible\n");
         printf("\n");
     }
     return 0;
 }
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=30;
bool vis[maxn][maxn];
int path[100][2];
int n,m;
int next[8][2]={-2,-1,-2,1,-1,-2,-1,2,1,-2,1,2,2,-1,2,1};
bool flag;
void dfs(int x,int y,int step){
    if(step==m*n){
        flag=true;
        for(int i=0;i<step;i++){
            printf("%c%d",path[i][1]+'A'-1,path[i][0]);
        }
        printf("\n");
    }
   else
    for(int k=0;k<8;k++){
        int tx=x+next[k][1];
        int ty=y+next[k][0];
        if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&!vis[tx][ty]&&!flag){
            vis[tx][ty]=true;
            path[step][0]=tx;
            path[step][1]=ty;
            dfs(tx,ty,step+1);
            vis[tx][ty]=false;
        }
    }

}

int main(){
   int t;
   scanf("%d",&t);
   int Case=0;
   while(t--){
        Case++;
       memset(vis,false,sizeof(vis));
       memset(path,0,sizeof(path));
       scanf("%d%d",&n,&m);
       flag=false;
       vis[1][1]=true;
       path[0][0]=1;
       path[0][1]=1;
      printf("Scenario #%d:\n",Case);
       dfs(1,1,1);
       if(!flag)
        printf("impossible\n");

        printf("\n");
   }
   return 0;
}

 

大意很明了,就是找到一个路径让马走完所有的点,不重复不遗漏;思路很容易找到,直接用DFS搜索标记并回溯,一个点一个点作为起点去试;找到后停止;

 

posted @ 2015-08-16 13:56  柳下_MBX  阅读(159)  评论(0编辑  收藏  举报