POJ 1077 A*

链接:

http://poj.org/problem?id=1077

题意:

经典8数码问题,直接暴力bfs也能做,但是一定要先hash一下

题解:

这里的估价函数为当前状态下,所有的数字与其位置的之差的绝对值总和

话说我又被c++的string坑惨了

代码:

 31 int vis[MAXN];
 32 int fac[] = { 1,1,2,6,24,120,720,5040,40320,362880 };
 33
 34 int find(char s[]) {//康托展开
 35     int res = 0;
 36     bool has[10] = { 0 };
 37     rep(i, 0, 9) {
 38         int x = s[i] - ‘0‘, y = 0;
 39         rep(j, 1, x) if (!has[j]) y++;
 40         res += y*fac[8 - i];
 41         has[x] = 1;
 42     }
 43     return res;
 44 }
 45
 46 int get_h(const char s[]) {
 47     int res = 0;
 48     rep(i, 0, 9) res += abs(s[i] - ‘1‘ - i);
 49     return res;
 50 }
 51
 52 struct Node {
 53     char s[15];
 54     int g;
 55     Node(char s[], int g) :g(g) { strcpy(this->s, s); }
 56     const bool operator<(const Node &t) const {
 57         return g + get_h(s) > t.g + get_h(t.s);
 58     }
 59 };
 60
 61 priority_queue<Node> que;
 62
 63 int main() {
 64     char s[15];
 65     rep(i, 0, 9) {
 66         string t;
 67         cin >> t;
 68         if (t[0] == ‘x‘) s[i] = ‘9‘;
 69         else s[i] = t[0];
 70     }
 71     vis[find(s)] = 100;
 72     que.push(Node(s, 0));
 73     while (!que.empty()) {
 74         Node pre = que.top(); que.pop();
 75         int x = 0;
 76         while (pre.s[x] != ‘9‘) x++;
 77         if (x >= 3) {
 78             char ss[15];
 79             strcpy(ss, pre.s);
 80             ss[x] = ss[x - 3];
 81             ss[x - 3] = ‘9‘;
 82             if (!vis[find(ss)]) {
 83                 vis[find(ss)] = -3;
 84                 que.push(Node(ss, pre.g + 1));
 85             }
 86         }
 87         if (x < 6) {
 88             char ss[15];
 89             strcpy(ss, pre.s);
 90             ss[x] = ss[x + 3];
 91             ss[x + 3] = ‘9‘;
 92             if (!vis[find(ss)]) {
 93                 vis[find(ss)] = 3;
 94                 que.push(Node(ss, pre.g + 1));
 95             }
 96         }
 97         if (x % 3) {
 98             char ss[15];
 99             strcpy(ss, pre.s);
100             ss[x] = ss[x - 1];
101             ss[x - 1] = ‘9‘;
102             if (!vis[find(ss)]) {
103                 vis[find(ss)] = -1;
104                 que.push(Node(ss, pre.g + 1));
105             }
106         }
107         if (x % 3 != 2) {
108             char ss[15];
109             strcpy(ss, pre.s);
110             ss[x] = ss[x + 1];
111             ss[x + 1] = ‘9‘;
112             if (!vis[find(ss)]) {
113                 vis[find(ss)] = 1;
114                 que.push(Node(ss, pre.g + 1));
115             }
116         }
117         if (vis[0]) break;
118     }
119     if (!vis[0]) return puts("unsolvable"), 0;
120     int y = 0;
121     char ss[15] = "123456789";
122     string ans;
123     while (vis[y] != 100) {
124         int x = 0;
125         while (ss[x] != ‘9‘) x++;
126         switch (vis[y]) {
127         case -3: {
128             ss[x] = ss[x + 3];
129             ss[x + 3] = ‘9‘;
130             ans += ‘u‘;
131             break;
132         }
133         case 3: {
134             ss[x] = ss[x - 3];
135             ss[x - 3] = ‘9‘;
136             ans += ‘d‘;
137             break;
138         }
139
140         case -1: {
141             ss[x] = ss[x + 1];
142             ss[x + 1] = ‘9‘;
143             ans += ‘l‘;
144             break;
145         }
146         case 1: {
147             ss[x] = ss[x - 1];
148             ss[x - 1] = ‘9‘;
149             ans += ‘r‘;
150             break;
151         }
152         }
153         y = find(ss);
154     }
155     reverse(all(ans));
156     cout << ans << endl;
157     return 0;
158 }
时间: 2024-10-26 10:33:56

POJ 1077 A*的相关文章

POJ - 1077 Eight

题意:经典八数码问题 思路:HASH+BFS #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 500000; const int size = 1000003; typedef int State[9]; char str[30]; int state[9],goal[9]={

HDU 1043 POJ 1077 八数码问题

以下内容转载自:http://www.cnblogs.com/goodness/archive/2010/05/04/1727141.html 八数码的八境界 研究经典问题,空说不好,我们拿出一个实际的题目来演绎.八数码问题在北大在线测评系统中有一个对应的题,题目描述如下: Eight Time Limit: 1000MS    Memory Limit: 65536K  Special Judge Description The 15-puzzle has been aroundfor ove

poj 1077 八数码(BFS+康托展开)

1 /* 2 题意:八数码问题,给出3*3的矩阵含1~8以及x,给出一个符合的解使得移动后的矩阵的顺序为1~8,最后为x 3 4 题解:BFS 5 需要用到康托展开来表示状态,不然数组无法完全表示所有状态,这样BFS就无法判断找不到解的情况(status 6 的0ms,0KB究竟是怎么做到的,简直不能想象=.=) 7 */ 8 #include <cstdio> 9 #include <cstring> 10 #include <queue> 11 #include &

POJ 1077 Eight(康托展开+BFS)

Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30176   Accepted: 13119   Special Judge Description The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15

HDU - 1043 - Eight / POJ - 1077 - Eight

先上题目: Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 11243    Accepted Submission(s): 3022Special Judge Problem Description The 15-puzzle has been around for over 100 years; even if you

poj 1077 Eight(双向bfs)

题目链接:http://poj.org/problem?id=1077 思路分析:题目要求在找出最短的移动路径,使得从给定的状态到达最终状态. <1>搜索算法选择:由于需要找出最短的移动路径,所以选择bfs搜索 <2>判重方法: 将空格视为数字9,则可以将状态的集合视为1-9的排列组合的集合,根据康托展开,将每一个状态映射到一个正整数中: 在由哈希表进行判重. <3>状态压缩:在搜索时使用将每个状态转换为一个由1-9组成的9位数字即可进行状态压缩与解压. <4&g

Eight hdu 1043 poj 1077

Description The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile mis

BFS(八数码) POJ 1077 || HDOJ 1043 Eight

题目传送门1 2 题意:从无序到有序移动的方案,即最后成1 2 3 4 5 6 7 8 0 分析:八数码经典问题.POJ是一次,HDOJ是多次.因为康托展开还不会,也写不了什么,HDOJ需要从最后的状态逆向搜索,这样才不会超时.判重康托展开,哈希也可. POJ //#include <bits/stdc++.h> #include<iostream> #include<algorithm> #include<string> #include<stack

poj 1077 八数码

这道题花了我一晚上去了看了一种解法,结果最后悲剧了,只在poj上过了,在hdu上TLE,原因是因为hdu上是多组数 据,而poj上是一组数据...悲剧啊,学的方法有点低效... 不过那个打印路径方法倒是可以借鉴一下,从终点往起点递归,打印路径... 贴代码: #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> using namespace std; #define