zoukankan      html  css  js  c++  java
  • 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("
    ");
             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:
    ",m+1);
             find(0,0,1);
             if(!g) printf("impossible
    ");
             printf("
    ");
         }
         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("
    ");
        }
       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:
    ",Case);
           dfs(1,1,1);
           if(!flag)
            printf("impossible
    ");
    
            printf("
    ");
       }
       return 0;
    }

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

     

  • 相关阅读:
    cygwin补充安装gcc/g++的方法
    JS中获取request的值,非常好用的JS代码
    登录页面跳出框架的JS
    asp.net DataTable转JSON
    ASP.NET文件下载的实用方法
    史上最牛X到的身份证号码验证,测试误差为0
    nopcommerce插件深度剖析
    C# foreach,linq,delegate集合查询的性能比较
    jquery tab插件精简版
    建议博客园成立中国的开源项目组织,同意的顶起
  • 原文地址:https://www.cnblogs.com/13224ACMer/p/4734258.html
Copyright © 2011-2022 走看看