• 骑士精神 ← IDA*


    【题目来源】
    https://www.acwing.com/problem/content/description/197/
    https://www.luogu.com.cn/problem/P2324

    【题目描述】
    在一个 5×5 的棋盘上有 12 个白色的骑士和 12 个黑色的骑士,且有一个空位。
    在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为 1,纵坐标相差为 2 或者横坐标相差为 2,纵坐标相差为 1 的格子)移动到空位上。
    给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘:为了体现出骑士精神,他们必须以最少的步数完成任务。

     【输入格式】
    第一行有一个正整数 T,表示一共有 T 组数据。
    接下来有 T 个 5×5 的矩阵,0 表示白色骑士,1 表示黑色骑士,* 表示空位。
    两组数据之间没有空行。

    【输出格式】
    每组数据输出占一行。
    如果能在 15 步以内(包括 15 步)到达目标状态,则输出步数,否则输出 −1。


    【数据范围】
    1≤T≤10

    【输入样例】
    2
    10110
    01*11
    10111
    01001
    00000
    01011
    110*1
    01110
    01010
    00100


    【输出样例】
    7
    -1

    【算法代码】

    1. #include
    2. using namespace std;
    3. int n;
    4. int a[5][5];
    5. int dx[]= {1,-1,-1,1,2,-2,-2,2};
    6. int dy[]= {2,-2,2,-2,1,-1,1,-1};
    7. //black:-1 white:1 void:0
    8. int goal[5][5]= {
    9. -1,-1,-1,-1,-1,
    10. 1,-1,-1,-1,-1,
    11. 1,1,0,-1,-1,
    12. 1,1,1,1,-1,
    13. 1,1,1,1,1
    14. };
    15. int h() { //evaluation function
    16. int res=0;
    17. for(int i=0; i<5; i++)
    18. for(int j=0; j<5; j++)
    19. if(a[i][j] && a[i][j]!=goal[i][j]) res++;
    20. return res;
    21. }
    22. bool check(int x, int y) { //Determine if cross the line
    23. if(x<0||x>=5||y<0||y>=5) return false;
    24. return true;
    25. }
    26. bool dfs(int cur,int x,int y,int dep) {
    27. if(!h()) return true;
    28. if(cur+h()>dep) return false;
    29. for(int i=0; i<8; i++) {
    30. int tx=x+dx[i];
    31. int ty=y+dy[i];
    32. if(!check(tx,ty)) continue;
    33. swap(a[x][y],a[tx][ty]);
    34. if(dfs(cur+1,tx,ty,dep)) return true;
    35. swap(a[x][y],a[tx][ty]);
    36. }
    37. return false;
    38. }
    39. int main() {
    40. int T;
    41. cin>>T;
    42. while(T--) {
    43. int x,y;
    44. for(int i=0; i<5; i++)
    45. for(int j=0; j<5; j++) {
    46. char c;
    47. cin>>c;
    48. if(c=='0') a[i][j]=1;
    49. else if(c=='1') a[i][j]=-1;
    50. else a[i][j]=0,x=i,y=j;
    51. }
    52. bool flag=1;
    53. for(int maxd=0; maxd<=15; maxd++) {
    54. if(dfs(0,x,y,maxd)) {
    55. cout<
    56. flag=0;
    57. break;
    58. }
    59. }
    60. if(flag) cout<<-1<
    61. }
    62. return 0;
    63. }
    64. /*
    65. in:
    66. 2
    67. 10110
    68. 01*11
    69. 10111
    70. 01001
    71. 00000
    72. 01011
    73. 110*1
    74. 01110
    75. 01010
    76. 00100
    77. out:
    78. 7
    79. -1
    80. */

    【参考文献】
    https://www.acwing.com/solution/content/8733/
    https://www.codenong.com/p12110852/
    https://blog.csdn.net/wl7777777777/article/details/124259366


     

  • 相关阅读:
    网络安全-渗透测试
    JDK8中ConcurrentHashMap底层源码解析-put和putVal方法以及数组的初始化
    Git入门实战教程之创建版本库
    Linux-查看服务器--硬件配置信息
    debian apt安装mysqlodbc
    硅谷(12)菜单管理
    基于Haar-Like特征的人脸检测算法研究-附Matlab代码
    循环结构 ----- for/in 语句 与 for/of语句
    Java集合框架(二)Set
    【网络教程】IPtables官方教程--学习笔记3
  • 原文地址:https://blog.csdn.net/hnjzsyjyj/article/details/126573461