zoj 1217 雙向BFS,記憶化搜尋、A*演算法實現

來源:互聯網
上載者:User

題目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1217

 

/*<br />POJ Statue: 7287094 qlyzpqz 1077 Accepted 1680K 32MS C++ 3541B 2010-07-29 13:36:54<br />ZOJ Statue: Statue: 2246164 2010-07-29 13:08:48 Accepted 1217 C++ 1520 25700 liushui<br />*/<br />//A*實現:<br />#include <iostream><br />#include <cstdio><br />#include <math.h><br />#include <time.h><br />#include <algorithm><br />using namespace std;</p><p>const int maxn = 362885;</p><p>struct NType<br />{<br />int statue[10];<br />int place;<br />int pre;<br />int step;<br />char opt;<br />};</p><p>struct HType<br />{<br />int pos;<br />int val;<br />};</p><p>bool cmp (struct HType a, struct HType b)<br />{<br />return a.val > b.val;<br />}</p><p>int dirx[] = {-1, 0, 0, 1};<br />int diry[] = {0, -1, 1, 0};<br />int poschg[] = {-3, -1, 1, 3};<br />char op[] = "ulrd";</p><p>int move (NType s, NType &e, int optNum, int pre)<br />{<br />int i, j, tr, tc, tp;</p><p>i = s.place / 3;<br />j = s.place % 3;</p><p>tr = i + dirx[optNum];<br />tc = j + diry[optNum];<br />if (tr >= 0 && tr < 3 && tc >= 0 && tc < 3)<br />{<br />e = s;<br />tp = e.place;<br />e.place += poschg[optNum];<br />e.statue[tp] = e.statue[e.place];<br />e.statue[e.place] = 0;<br />e.pre = pre;<br />e.opt = op[optNum];<br />e.step++;<br />return 1;<br />}</p><p>return 0;<br />}</p><p>int dist (int * statue, int place)<br />{<br />int ret = 0;<br />statue[place] = 9;<br />for (int i = 0, j; i < 9; i++)<br />{<br />j = statue[i] - 1;<br />ret += abs(i / 3 - j / 3) + abs(i % 3 - j % 3);<br />}<br />statue[place] = 0;<br />return ret;<br />}</p><p>int fact[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320};</p><p>int cantor (int * statue)<br />{<br />int ans = 0, num = 0, n = 8;<br />int flag[10] = {0};<br />for (int i = 0; i < 9; i++)<br />{<br />int up = statue[i];<br />flag[up] = 1;<br />num = 0;<br />for (int k = 0; k < up; k++) if (!flag[k]) num++;<br />ans += num * fact[n];<br />n--;<br />}<br />return ans;<br />}</p><p>int sst[10], est[10], splace, eplace, vis[maxn];<br />NType queue[maxn];<br />HType heap[maxn];<br />int head, rear, hp;</p><p>void output (int pos)<br />{<br />if (pos == 0) return;<br />output(queue[pos].pre);<br />putchar(queue[pos].opt);<br />}</p><p>void AStar ()<br />{<br />int rcode, pos = -1, ecode, scode;<br />head = rear = hp = 0;<br />memcpy(queue[rear].statue, sst, sizeof(sst));<br />scode = cantor(sst);<br />ecode = cantor(est);<br />queue[rear].place = splace;<br />queue[rear].pre = -1;<br />queue[rear].step = 0;<br />vis[scode] = 1;<br />rear++;<br />heap[hp].pos = 0;<br />heap[hp].val = 10 * dist(queue[head].statue, splace); //用dist + step TLE<br />hp++;</p><p>if (scode == ecode) {pos = 0; goto lable;}<br />while (hp > 0)<br />{<br />head = heap[0].pos;<br />pop_heap(heap, heap + hp, cmp);<br />hp--;<br />for (int i = 0; i < 4; i++)<br />{<br />if (move(queue[head], queue[rear], i, head))<br />{<br />rcode = cantor(queue[rear].statue);<br />if (vis[rcode]) continue;<br />vis[rcode] = 1;<br />heap[hp].pos = rear;<br />heap[hp].val = 10 * dist(queue[rear].statue, queue[rear].place) + queue[rear].step;<br />push_heap(heap, heap + (++hp), cmp);<br />rear++;<br />if (ecode == rcode) {pos = rear - 1; goto lable;}<br />}<br />}<br />}<br />lable:<br />output(pos);<br />}</p><p>bool isSolveable (int *statue)<br />{<br />int arr[10], n = 0, num = 0;<br />for (int i = 0; i < 9; i++)<br />{<br />if (statue[i] != 0) arr[++n] = statue[i];<br />}<br />for (int i = 1; i <= 8; i++)<br />{<br />for (int j = i + 1; j <= 8; j++)<br />{<br />if (arr[i] > arr[j]) num++;<br />}<br />}<br />if (num & 0x1) return false;<br />return true;<br />}</p><p>int main ()<br />{<br />char c;<br />freopen("input.txt", "r", stdin);</p><p>for (int i = 0; i < 8; i++) est[i] = i + 1;<br />est[8] = 0; eplace = 8;</p><p>while (1)<br />{<br />for (int i = 0; i < 9; i++)<br />{<br />if (scanf(" %c", &c) == EOF)<br />{<br />//printf("Time : %.6lf/n", (double)clock() / CLOCKS_PER_SEC);<br />return 0;<br />}<br />if (c == 'x')<br />{<br />sst[i] = 0;<br />splace = i;<br />}<br />else sst[i] = c - '0';<br />}<br />memset(vis, 0, sizeof(vis));</p><p>if (isSolveable(sst))<br />{<br />AStar();<br />putchar('/n');<br />}<br />else printf("unsolvable/n");<br />}</p><p>return 0;<br />}  

 

/*<br />ZOJ Statue: 2245819 2010-07-28 21:21:44 Accepted 1217 C++ 4350 20384 liushui<br />POJ Statue: 7281689 qlyzpqz 1077 Accepted 4084K 16MS C++ 3986B 2010-07-28 21:22:26<br />*/<br />//雙向廣搜<br />#include <iostream><br />#include <cstdio><br />#include <string.h><br />using namespace std;</p><p>const int maxn = 181445;</p><p>struct SType<br />{<br />int statue[10];<br />int place;<br />int step;</p><p>SType () {}<br />SType (int *a, int p, int s)<br />{<br />for (int i = 0; i < 9; i++)<br />{<br />statue[i] = a[i];<br />}<br />place = p;<br />step = s;<br />}<br />};</p><p>int dirx[] = {-1, 0, 0, 1};<br />int diry[] = {0, -1, 1, 0};<br />int poschg[] = {-3, -1, 1, 3};</p><p>int move (SType s, SType &e, int optNum)<br />{<br />int i, j, tr, tc, tp;</p><p>i = s.place / 3;<br />j = s.place % 3;</p><p>tr = i + dirx[optNum];<br />tc = j + diry[optNum];<br />if (tr >= 0 && tr < 3 && tc >= 0 && tc < 3)<br />{<br />e = s;<br />tp = e.place;<br />e.place += poschg[optNum];<br />e.statue[tp] = e.statue[e.place];<br />e.statue[e.place] = 0;<br />e.step++;<br />return 1;<br />}</p><p>return 0;<br />}</p><p>int fact[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320};</p><p>int cantor (SType s)<br />{<br />int ans = 0, num = 0, n = 8;<br />int flag[10] = {0};<br />for (int i = 0; i < 9; i++)<br />{<br />int up = s.statue[i];<br />flag[up] = 1;<br />num = 0;<br />for (int k = 0; k < up; k++) if (!flag[k]) num++;<br />ans += num * fact[n];<br />n--;<br />}<br />return ans;<br />}</p><p>inline bool isEnd (SType s)<br />{<br />if (s.place != 8) return false;<br />if (s.statue[0] == 1 && s.statue[1] == 2 && s.statue[2] == 3 &&<br />s.statue[3] == 4 && s.statue[4] == 5 && s.statue[5] == 6 &&<br />s.statue[6] == 7 && s.statue[7] == 8 && s.statue[8] == 0)<br />{<br />return true;<br />}<br />return false;<br />}</p><p>SType q1[maxn], q2[maxn];<br />int head1, rear1, head2, rear2, vis[2 * maxn], parent[2 * maxn];<br />char preOpt[2 * maxn];</p><p>void output1 (int code, int scode)<br />{<br />if (code == scode) return;<br />output1(parent[code], scode);<br />putchar(preOpt[code]);<br />}</p><p>void output2 (int code, int ecode)<br />{<br />if (code == ecode) return;<br />putchar(preOpt[code]);<br />output2(parent[code], ecode);<br />}</p><p>void bfs (SType start)<br />{<br />char opt1[] = "ulrd", opt2[] = "drlu";<br />int estatue[] = {1, 2, 3, 4, 5, 6, 7, 8, 0}, ucode, rcode, ok = 0,<br />scode, ecode;<br />SType end(estatue, 8, 0), u;</p><p>scode = cantor(start);<br />ecode = cantor(end);<br />head1 = rear1 = head2 = rear2 = 0;<br />q1[rear1++] = start;<br />q2[rear2++] = end;<br />vis[scode] = 1;<br />vis[ecode] = 2;</p><p>while (1)<br />{<br />//正向搜尋<br />if (head1 < rear1)<br />{<br />u = q1[head1++];<br />ucode = cantor(u);<br />for (int i = 0; i < 4; i++)<br />{<br />if (move(u, q1[rear1], i))<br />{<br />rcode = cantor(q1[rear1]);<br />if (vis[rcode] == 1) continue;<br />rear1++;<br />if (vis[rcode] == 2 || rcode == ecode)<br />{<br />output1(ucode, scode);<br />putchar(opt1[i]);<br />output2(rcode, ecode);<br />return;<br />}<br />vis[rcode] = 1;<br />parent[rcode] = ucode;<br />preOpt[rcode] = opt1[i];<br />}<br />}<br />}</p><p>//反向搜尋<br />if (head2 < rear2)<br />{<br />u = q2[head2++];<br />ucode = cantor(u);<br />for (int i = 0; i < 4; i++)<br />{<br />if (move(u, q2[rear2], i))<br />{<br />rcode = cantor(q2[rear2]);<br />if (vis[rcode] == 2) continue;<br />rear2++;<br />if (vis[rcode] == 1 || rcode == ecode)<br />{<br />output1(rcode, scode);<br />putchar(opt2[i]);<br />output2(ucode, ecode);<br />return;<br />}<br />vis[rcode] = 2;<br />parent[rcode] = ucode;<br />preOpt[rcode] = opt2[i];<br />}<br />}<br />}<br />}<br />}</p><p>bool isSolveable (SType s)<br />{<br />int arr[10], n = 0, num = 0;<br />for (int i = 0; i < 9; i++)<br />{<br />if (s.statue[i] != 0) arr[++n] = s.statue[i];<br />}<br />for (int i = 1; i <= 8; i++)<br />{<br />for (int j = i + 1; j <= 8; j++)<br />{<br />if (arr[i] > arr[j]) num++;<br />}<br />}<br />if (num & 0x1) return false;<br />return true;<br />}</p><p>int main ()<br />{<br />freopen("input.txt", "r", stdin);</p><p>SType start;<br />char c;<br />while (1)<br />{<br />for (int i = 0; i < 9; i++)<br />{<br />if (scanf(" %c", &c) == EOF) return 0;<br />if (c == 'x')<br />{<br />start.statue[i] = 0;<br />start.place = i;<br />}<br />else start.statue[i] = c - '0';<br />}<br />start.step = 0;<br />memset(vis, 0, sizeof(vis));</p><p>if (isSolveable(start))<br />{<br />bfs(start);<br />putchar('/n');<br />}<br />else printf("unsolvable/n");<br />}</p><p>return 0;<br />}   

/*<br />ZOJ Statue: 2245603 2010-07-28 17:01:42 Accepted 1217 C++ 420 21092 liushui<br />*/<br />/*記憶化搜尋:按廣度優先搜尋找到從起始點到終點的路徑,當找到一條路徑時,隊列中的其他節點到終點也一定存在著路徑(不一定最短),只要遇到已經搜過的點,則說明找到了一條路徑<br />*/<br />#include <iostream><br />#include <cstdio><br />#include <assert.h><br />using namespace std;</p><p>const int maxn = 362885; // 9!<br />const int inf = maxn;</p><p>struct SType<br />{<br />int statue[10];<br />int pos;<br />int step;<br />};</p><p>int dirx[] = {-1, 0, 0, 1};<br />int diry[] = {0, -1, 1, 0};<br />int poschg[] = {-3, -1, 1, 3};<br />int move (SType s, SType &e, int optNum)<br />{<br />int i, j, tr, tc, tp;</p><p>i = s.pos / 3;<br />j = s.pos % 3;</p><p>tr = i + dirx[optNum];<br />tc = j + diry[optNum];<br />if (tr >= 0 && tr < 3 && tc >= 0 && tc < 3)<br />{<br />e = s;<br />tp = e.pos;<br />e.pos += poschg[optNum];<br />e.statue[tp] = e.statue[e.pos];<br />e.statue[e.pos] = 0;<br />e.step++;<br />return 1;<br />}</p><p>return 0;<br />}</p><p>int fact[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320};<br />int cantor (SType s)<br />{<br />int ans = 0, num = 0, n = 8;<br />int flag[10] = {0};<br />for (int i = 0; i < 9; i++)<br />{<br />int up = s.statue[i];<br />flag[up] = 1;<br />num = 0;<br />for (int k = 0; k < up; k++) if (!flag[k]) num++;<br />ans += num * fact[n];<br />n--;<br />}<br />return ans;<br />}</p><p>inline bool isEnd (SType s)<br />{<br />if (s.pos != 8) return false;<br />if (s.statue[0] == 1 && s.statue[1] == 2 && s.statue[2] == 3 &&<br />s.statue[3] == 4 && s.statue[4] == 5 && s.statue[5] == 6 &&<br />s.statue[6] == 7 && s.statue[7] == 8 && s.statue[8] == 0)<br />{<br />return true;<br />}<br />return false;<br />}</p><p>bool vis[maxn];<br />SType q[maxn];<br />int parent[maxn], scode, path[maxn];<br />char preopt[maxn], nextopt[maxn];</p><p>void bfs (SType start)<br />{<br />char optArr[] = "ulrd";<br />int head, rear, code, t, ecode = 46233, ok = 0;<br />SType u;<br />head = rear = 0;<br />q[rear++] = start;<br />scode = cantor(start);;<br />t = scode;<br />vis[scode] = true;<br />if (isEnd(start) || path[scode] != -1)<br />{<br />ok = 1;<br />}<br />while (head < rear && !ok)<br />{<br />u = q[head++];<br />code = cantor(u);<br />for (int i = 0; i < 4 && !ok; i++)<br />{<br />if (move(u, q[rear], i) && !vis[t = cantor(q[rear])])<br />{<br />vis[t] = true;<br />parent[t] = code;<br />preopt[t] = optArr[i];<br />rear++;<br />if (isEnd(q[rear-1]) || path[t] != -1)<br />{<br />ok = 1;<br />for (int j = t; j != scode; j = parent[j])<br />{<br />assert(path[parent[j]] == -1);<br />path[parent[j]] = j;<br />nextopt[parent[j]] = preopt[j];<br />}<br />for (int j = 1; j < rear; j++)<br />{<br />int tmp = cantor(q[j]);<br />if (path[tmp] == -1)<br />{<br />path[tmp] = parent[tmp];<br />switch (preopt[tmp])<br />{<br />case 'l':<br />nextopt[tmp] = 'r'; break;<br />case 'r':<br />nextopt[tmp] = 'l'; break;<br />case 'u':<br />nextopt[tmp] = 'd'; break;<br />case 'd':<br />nextopt[tmp] = 'u'; break;<br />}<br />}<br />}<br />}<br />}<br />}<br />}</p><p>for (int i = scode; i != ecode && path[i] != -1; i = path[i])<br />{<br />putchar(nextopt[i]);<br />}<br />putchar('/n');<br />}</p><p>bool isSolveable (SType s)<br />{<br />int arr[10], n = 0, num = 0;<br />for (int i = 0; i < 9; i++)<br />{<br />if (s.statue[i] != 0) arr[++n] = s.statue[i];<br />}<br />for (int i = 1; i <= 8; i++)<br />{<br />for (int j = i + 1; j <= 8; j++)<br />{<br />if (arr[i] > arr[j]) num++;<br />}<br />}<br />if (num & 0x1) return false;<br />return true;<br />}</p><p>int main ()<br />{<br />freopen("input.txt", "r", stdin);</p><p>SType start;<br />char c;</p><p>memset(path, -1, sizeof(path));</p><p>while (1)<br />{<br />for (int i = 0; i < 9; i++)<br />{<br />if (scanf(" %c", &c) == EOF) return 0;<br />if (c == 'x' || c == 'X')<br />{<br />start.statue[i] = 0;<br />start.pos = i;<br />}<br />else start.statue[i] = c - '0';<br />}<br />start.step = 0;<br />memset(vis, 0, sizeof(vis));<br />if (!isSolveable(start)) printf("unsolvable/n");<br />else bfs(start);<br />}</p><p>return 0;<br />}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.