• UVa 1343 旋转游戏(dfs+IDA*)


    https://vjudge.net/problem/UVA-1343

    题意:如图所示,一共有8个1,8个2和8个3,如何以最少的移动来使得中间8个格子都为同一个数。

    思路:状态空间搜索问题。

            用IDA*算法的话会比较快,而且代码比较简洁。

            IDA*的关键就是要寻找一个估价函数h(),在这道题目中,每次移动最多只会使一个格子的数字正确,所以当maxd-d<h()时便可以剪枝。

     1 #include<iostream>
     2 #include<string>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 int position[8][7] =    { 
     8                         { 0, 2, 6, 11, 15, 20, 22 }, { 1, 3, 8, 12, 17, 21, 23 },  //八个方向格子的坐标值
     9                         { 10, 9, 8, 7, 6, 5, 4},  { 19, 18, 17, 16, 15, 14, 13 },
    10                         {23, 21, 17, 12, 8, 3, 1}, { 22, 20, 15, 11, 6, 2, 0 },
    11                         {13, 14, 15, 16, 17, 18, 19}, { 4, 5, 6, 7, 8, 9, 10 }
    12                         };
    13 
    14 int goal[] = { 6, 7, 8, 11, 12, 15, 16, 17 }; //目标状态的坐标
    15 
    16 int a[25];
    17 char order[30];     //记录路径
    18 
    19 bool is_goal()  //判断是否已达到目标状态
    20 {
    21     for (int i = 0; i < 7; i++)
    22     {
    23         if (a[goal[i]]!=a[goal[i + 1]])    return false;
    24     }
    25     return true;
    26 }
    27 
    28 int h()  //算出不匹配的最小值
    29 {
    30     int n1 = 0, n2 = 0, n3 = 0;
    31     for (int i = 0; i < 8; i++)
    32     {
    33         if (a[goal[i]] == 1) n1++;
    34         else if (a[goal[i]] == 2)  n2++;
    35         else if (a[goal[i]] == 3)  n3++;
    36     }
    37     return 8 -max( max(n1, n2),n3);
    38 }
    39 
    40 void rotate(int k)  //往指定的方向移动
    41 {
    42     int temp = a[position[k][0]]; 
    43     for (int i = 1; i < 7; i++)
    44     {
    45         a[position[k][i-1]] = a[position[k][i]];
    46     }
    47     a[position[k][6]] = temp;
    48 }
    49 
    50 bool dfs(int d, int maxd)
    51 {
    52     if (is_goal())    return true;
    53     if (maxd - d < h())    return false;  //剪枝
    54     int old[25];   //用来保存原来的序列
    55     memcpy(old, a, sizeof(a));
    56     for (int i = 0; i < 8; i++)
    57     {
    58         rotate(i); //往第i个方向移动
    59         order[d] = i + 'A';
    60         if (dfs(d + 1, maxd))  return true;
    61         memcpy(a, old, sizeof(old)); //如果失败,则恢复原来序列
    62     }
    63     return false;
    64 }
    65 
    66 void solve()
    67 {
    68     if (is_goal())
    69     {
    70         cout << "No moves needed" << endl << a[6] << endl;
    71         return;
    72     }
    73     for (int maxd = 1;; maxd++)
    74     {
    75         if (dfs(0, maxd))
    76         {
    77             order[maxd] = '';
    78             cout << order << endl << a[6] << endl;
    79             return;
    80         }
    81     }
    82 }
    83 
    84 int main()
    85 {
    86     //freopen("D:\txt.txt", "r", stdin);
    87     while (cin >> a[0] && a[0])
    88     {
    89         for (int i = 1; i < 24; i++)
    90             cin >> a[i];
    91         solve();
    92     }
    93     return 0;
    94 }
  • 相关阅读:
    Stm32CubeMX5 配置 STM32的串口DMA接受方式 --- 基于 stm32f051k8u6
    Stm32 控制1.44寸液晶显示图片 基于stm32f051k8u6
    makefile自动编译
    Stm32CubeMX5 创建LED控制工程
    ARM 汇编与C之间 的调用
    shell 脚本文件类型.sh ,变量
    bzoj3589 动态树 求链并 容斥
    bzoj2287【POJ Challenge】消失之物 缺一01背包
    bzoj2916: [Poi1997]Monochromatic Triangles 思路
    [NOI2010]超级钢琴 主席树
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6346564.html
Copyright © 2020-2023  润新知