• UVa 10181 15Puzzle Problem


    题目链接不好找:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1122

    用的 IDA*,跑了6.536s,时限是45s(刚看了627个人通过,我是第515名……,排行榜比较恐怖啊,见下图)

    这道题的逆序剪枝和八数码不同,具体参考这篇文章:http://mathworld.wolfram.com/15Puzzle.html
    1A!

      1 # include <stdio.h>
      2 # include <math.h>
      3 # include <string.h>
      4 
      5 # define MIN(x, y) ((x)<(y) ? (x):(y))
      6 
      7 # define SIZE 4
      8 # define N SIZE*SIZE
      9 # define DIR_N 4
     10 # define INF 0x7fffffff
     11 # define MAX_DEPTH 1000
     12 
     13 char solved;
     14 char start[N], goal[N];
     15 char cur[N];
     16 
     17 int bound;
     18 const char md[] = {'U', 'L', 'R', 'D'};
     19 const short int dir[][2] = {{-1,0}, {0,-1}, {0,1}, {1,0}};
     20 char path[MAX_DEPTH];
     21 
     22 void solve(void);
     23 void read(char *s);
     24 int IDAstar(void);
     25 char inv_judge(char *s);
     26 int heu(void);
     27 int dfs(int zero_pos, int depth, char direction);
     28 
     29 int main()
     30 {
     31     int i, T;
     32         
     33     scanf("%d", &T);
     34     for (i = 0; i < N-1; ++i)
     35         goal[i] = i + 1;
     36     goal[N-1] = 0;
     37     for (i = 1; i <= T; ++i)
     38     {
     39         read(start);
     40         memcpy(cur, start, N);
     41         solve();
     42     }
     43     
     44     return 0;
     45 }
     46 
     47 void solve()
     48 {
     49     int i, depth;
     50 
     51     if (inv_judge(start)) puts("This puzzle is not solvable.");
     52     else
     53     {
     54         memset(path, -1, sizeof(path));
     55         depth = IDAstar();
     56         for (i = 0; path[i]!=-1; ++i)
     57         {
     58             putchar(md[path[i]]);
     59         }
     60         putchar('\n');
     61     }
     62 }
     63 
     64 void read(char *s)
     65 {
     66     int i, t;
     67 
     68     for (i = 0; i < N; ++i)
     69     {
     70         scanf("%d", &t);
     71         s[i] = t;
     72     }
     73 }
     74 
     75 int IDAstar(void)
     76 {
     77     int i;
     78 
     79     solved = 0;
     80     bound = heu();
     81 
     82     for (i = 0; start[i] && i < N; ++i) ;
     83 
     84     while (!solved && bound<100)
     85     {
     86         bound = dfs(i, 0, -10);
     87     }
     88 
     89     return bound;
     90 }
     91 
     92 int dfs(int pos, int depth, char d)
     93 {
     94     int h, i, nx, ny, npos, nbound, t;
     95 
     96     h = heu();
     97 
     98     if (depth+h > bound) return depth+h;
     99     if (h == 0)
    100     {
    101         solved = 1;
    102         return depth;
    103     }
    104 
    105     nbound = INF;
    106     for (i = 0; i < DIR_N; ++i)
    107     {
    108         if (i+d == DIR_N-1) continue;
    109         nx = pos/SIZE + dir[i][0];
    110         ny = pos%SIZE + dir[i][1];
    111         if (0<=nx && nx<SIZE && 0<=ny && ny<SIZE)
    112         {
    113             path[depth] = i;
    114             npos = nx*SIZE + ny;
    115             cur[pos] = cur[npos]; cur[npos] = 0;     /* pos -> npos */
    116             t = dfs(npos, depth+1, i);
    117             if (solved) return t;
    118             nbound = MIN(nbound, t);
    119             cur[npos] = cur[pos]; cur[pos] = 0;
    120         }
    121     }
    122     return nbound;
    123 }
    124 
    125 int heu(void)            /* return heu(cur_state) */
    126 {
    127     char ch;
    128     int i, j, ret;
    129 
    130     ret = 0;
    131     for (i = 0; i < N; ++i)
    132     {
    133         ch = goal[i];
    134         if (ch == 0) continue;
    135         for (j = 0; j < N; ++j)
    136         {
    137             if (ch == cur[j])
    138             {
    139                 ret = ret + abs(i/SIZE-j/SIZE) + abs(i%SIZE-j%SIZE);
    140             }
    141         }
    142     }
    143 
    144     return ret;
    145 }
    146 
    147 char inv_judge(char *s)
    148 {
    149     char ch, ret;
    150     int i, j;
    151 
    152     ret = 0;
    153     for (i = 0; i < N-1; ++i)
    154     {
    155         if ((ch = s[i]) == 0 && (i/SIZE+1)&0x1)
    156             ret = 1 - ret;
    157         for (j = i+1; j < N; ++j)
    158         {
    159             if (s[j] && s[j]<ch) ret = 1 - ret;
    160         }
    161     }
    162 
    163     return ret;
    164 }

    //

  • 相关阅读:
    codesmith 连接mysql
    数据库 价格字段 设置 decimal(8,2),价格为100W,只显示999999.99
    AOP和IOC
    Android Studio 每次运行都会再下载一遍,修改
    gradle 的jar下载到哪里了
    遇到的坑
    Error:Failed to resolve: :Base:
    re-download dependencies and 无法下载jar 的解决
    DI是实现面向切面和面向抽象的前提
    基础才是重中之重~ConcurrentDictionary让你的多线程代码更优美
  • 原文地址:https://www.cnblogs.com/JMDWQ/p/2520001.html
Copyright © 2020-2023  润新知