• sicily 1152 简单的马周游问题 and sicily 1153 马的周游问题


    1152:

    Description

    在一个5 * 6的棋盘中的某个位置有一只马,如果它走29步正好经过除起点外的其他位置各一次,这样一种走法则称马的周游路线,试设计一个算法,从给定的起点出发,找出它的一条周游路线。

    为了便于表示一个棋盘,我们按照从上到下,从左到右对棋盘的方格编号,如下所示:

    1     2     3       4     5     6

    7     8     9       10    11       12

    13    14       15    16       17    18

    19    20       21    22       23    24

    25    26       27    28       29    30

    马的走法是“日”字形路线,例如当马在位置 15 的时候,它可以到达 2  4  7  11  19  23  26  28 。但是规定马是不能跳出棋盘外的,例如从位置 1 只能到达 9  14 

    Input

    输入有若干行。每行一个整数 N(1<=N<=30) ,表示马的起点。最后一行用 -1 表示结束,不用处理。

    Output

    对输入的每一个起点,求一条周游线路。对应地输出一行,有 30 个整数,从起点开始按顺序给出马每次经过的棋盘方格的编号。相邻的数字用一个空格分开。

    Sample Input

    4
    -1
    

    Sample Output

    注意:如果起点和输入给定的不同,重复多次经过同一方格或者有的方格没有被经过,都会被认为是错误的。

    分析:

    本题集体思路为深度搜索方法。可以将本题棋盘各点组成一张无向图,图的边表示马的一步行走路线,两点连通即表示马可以由一点走“日”字到另外一点。这样建模后,题目所求解即为给定起点的一条“图遍历”路径(不是所有),明显深度搜索(DFS)更加合适。

    同时又要注意:1152数据量较小,测试数据也不多,可能会出现选择特定的移动向量,直接搜索即可通过的情况,但是1153则不行。所以还是老老实实进行剪枝,剪枝思路是优先遍历出度较少的子节点,可以大幅减少计算量。具体操作是计算并存储子节点出度,再对子节点按照出度排序,由低到高进行遍历,特别注意子节点的存储空间要在DFS函数中动态申请,否则会出错。

    PS:1152的题目数据很巧,其实是可以成环的,所以找到一条路径之后打表也是可以的,不过太偷懒了,就不这么做了。

    代码:

     1 // Problem#: 1152
     2 // Submission#: 1774802
     3 // The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
     4 // URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
     5 // All Copyright reserved by Informatic Lab of Sun Yat-sen University
     6 #include <iostream>
     7 #include <cstring>
     8 #include <vector>
     9 #include <algorithm>
    10 using namespace std;
    11 
    12 bool flag[5][6];
    13 int ans[30];
    14 int dir[8][2] = {-2,1,-1,2,1,2,2,1,2,-1,1,-2,-1,-2,-2,-1};
    15 
    16 inline bool judge(int x, int y){
    17     return x>=0 && x<5 && y>=0 && y <6 && !flag[x][y];
    18 }
    19 
    20 inline int degree(int a, int b){
    21     int re = 0;
    22     int x,y;
    23     for(int i = 0;i < 8;i++){  
    24         x = a + dir[i][0];  
    25         y = b + dir[i][1];  
    26         if(judge(x,y)) re++;  
    27     }  
    28     return re;
    29 }
    30 
    31 struct node{
    32     int x,y,c;
    33     node(){
    34     x = y = c = -1;
    35     }
    36     node(int a, int b){
    37     x = a;
    38     y = b;
    39     c = degree(a,b);
    40     }
    41 };
    42 
    43 
    44 inline bool cmp(node a, node b){
    45     return a.c<b.c;
    46 }
    47 
    48 inline node find(int n){
    49     node re;
    50     int x = (n-1) / 6;
    51     int y = (n-1) % 6;
    52     re = node(x,y);
    53     return re;
    54 }
    55 
    56 inline node calcu(node a,int c){
    57     node re;
    58     int x = a.x + dir[c][0];
    59     int y = a.y + dir[c][1];
    60     re = node(x,y);
    61     return re;
    62 }
    63 
    64 bool dfs(node a, int c){
    65     node t;
    66     vector<node> buffer;
    67     flag[a.x][a.y] = true;
    68     ans[c] = 6*a.x + a.y + 1;
    69     if( c == 29 ) return true;
    70     for( int i=0 ; i<8 ; i++ ){
    71     t = calcu(a,i);
    72     if(judge(t.x,t.y)) buffer.push_back(t);
    73     }
    74     sort(buffer.begin(),buffer.end(),cmp);
    75     for( int i=0 ; i<buffer.size() ; i++ )
    76     if( dfs(buffer[i],c+1) ) return true;
    77     flag[a.x][a.y] = false;
    78     return false;
    79 }
    80 
    81 int main(){
    82     int n;
    83     while( cin>>n && n>0 ){
    84     memset(flag,0,sizeof(flag));
    85     node s = find(n);
    86     dfs(s,0);
    87     cout << n;
    88     for( int i=1 ; i<30 ; i++ )
    89         cout << " " << ans[i];
    90     cout << endl;
    91     }
    92     return 0;
    93 }                                 

    1153与1152的问题相似,只是问题规模不同,不再重复叙述,只要改一下部分数组和函数的数据就可以,只附上代码即可。

    1153代码:

     1 // Problem#: 1153
     2 // Submission#: 1774794
     3 // The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
     4 // URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
     5 // All Copyright reserved by Informatic Lab of Sun Yat-sen University
     6 #include <iostream>
     7 #include <cstring>
     8 #include <vector>
     9 #include <algorithm>
    10 using namespace std;
    11 
    12 bool flag[8][8];
    13 int ans[64];
    14 int dir[8][2] = {-2,1,-1,2,1,2,2,1,2,-1,1,-2,-1,-2,-2,-1};
    15 
    16 inline bool judge(int x, int y){
    17     return x>=0 && x<8 && y>=0 && y <8 && !flag[x][y];
    18 }
    19 
    20 inline int degree(int a, int b){
    21     int re = 0;
    22     int x,y;
    23     for(int i = 0;i < 8;i++){  
    24         x = a + dir[i][0];  
    25         y = b + dir[i][1];  
    26         if(judge(x,y)) re++;  
    27     }  
    28     return re;
    29 }
    30 
    31 struct node{
    32     int x,y,c;
    33     node(){
    34     x = y = c = -1;
    35     }
    36     node(int a, int b){
    37     x = a;
    38     y = b;
    39     c = degree(a,b);
    40     }
    41 };
    42 
    43 
    44 inline bool cmp(node a, node b){
    45     return a.c<b.c;
    46 }
    47 
    48 inline node find(int n){
    49     node re;
    50     int x = (n-1) / 8;
    51     int y = (n-1) % 8;
    52     re = node(x,y);
    53     return re;
    54 }
    55 
    56 inline node calcu(node a,int c){
    57     node re;
    58     int x = a.x + dir[c][0];
    59     int y = a.y + dir[c][1];
    60     re = node(x,y);
    61     return re;
    62 }
    63 
    64 bool dfs(node a, int c){
    65     node t;
    66     vector<node> buffer;
    67     flag[a.x][a.y] = true;
    68     ans[c] = 8*a.x + a.y + 1;
    69     if( c == 63 ) return true;
    70     for( int i=0 ; i<8 ; i++ ){
    71     t = calcu(a,i);
    72     if(judge(t.x,t.y)) buffer.push_back(t);
    73     }
    74     sort(buffer.begin(),buffer.end(),cmp);
    75     for( int i=0 ; i<buffer.size() ; i++ )
    76     if( dfs(buffer[i],c+1) ) return true;
    77     flag[a.x][a.y] = false;
    78     return false;
    79 }
    80 
    81 int main(){
    82     int n;
    83     while( cin>>n && n>0 ){
    84     memset(flag,0,sizeof(flag));
    85     node s = find(n);
    86     dfs(s,0);
    87     cout << n;
    88     for( int i=1 ; i<64 ; i++ )
    89         cout << " " << ans[i];
    90     cout << endl;
    91     }
    92     return 0;
    93 }                                 
  • 相关阅读:
    Linux中的文件夹的增删改查命令和文件的增删改查命令
    xshell开源软件
    2020090808redis之linux的gcc的升级安装(八)
    2020090807redis之windows安装(七)
    2020090806redis之理解(六)
    2020090805redis之nosql的四大分类(五)
    每个牛逼的人都有一段苦逼的岁月,但是只要像SB一样坚持,终将牛逼
    2020090804redis之数据库的搭建(四)
    2020090803redis之大数据3V+3高(三)
    2020090802redis之非关系 数据库nosql(二)
  • 原文地址:https://www.cnblogs.com/ciel/p/2876750.html
Copyright © 2020-2023  润新知