Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

Re:优化编码 + 双向bfs

Posted by LittleOriole at 2026-08-22 13:06:59 on Problem 3131
In Reply To:优化编码 + 双向bfs Posted by:fogsail at 2019-07-23 21:27:02
> //
> //  main.cpp
> //  POJ3131-4
> //
> //  Created by zhangmin chen on 2019/7/22.
> //  Copyright © 2019 zhangmin chen. All rights reserved.
> //
> 
> #include <iostream>
> #include <cstdio>
> #include <cstring>
> #include <cstdlib>
> #include <algorithm>
> #include <queue>
> #include <vector>
> #include <stack>
> #include <map>
> #include <set>
> #include <sstream>
> #include <iomanip>
> #include <cmath>
> #include <bitset>
> #include <assert.h>
> 
> using namespace std;
> typedef long long llong;
> typedef set<int>::iterator ssii;
> 
> const int HASHSZ = 2000007;
> const int maxn = 2000007;
> 
> #define Cmp(a, b) memcmp(a, b, sizeof(b))
> #define Cpy(a, b) memcpy(a, b, sizeof(a))
> #define Set(a, v) memset(a, v, sizeof(a))
> #define debug(x) cout << #x << ": " << x << endl
> #define _forS(i, l, r) for(set<int>::iterator i = (l); i != (r); i++)
> #define _rep(i, l, r) for(int i = (l); i <= (r); i++)
> #define _for(i, l, r) for(int i = (l); i < (r); i++)
> #define _forDown(i, l, r) for(int i = (l); i >= r; i--)
> #define debug_(ch, i) printf(#ch"[%d]: %d\n", i, ch[i])
> #define debug_m(mp, p) printf(#mp"[%d]: %d\n", p->first, p->second)
> #define debugS(str) cout << "dbg: " << str << endl;
> #define debugArr(arr, x, y) _for(i, 0, x) { _for(j, 0, y) printf("%c", arr[i][j]); printf("\n"); }
> #define _forPlus(i, l, d, r) for(int i = (l); i + d < (r); i++)
> 
> class HASH {
> public:
>     struct Node {
>         int nxt, val;
>     } nodes[HASHSZ];
>     
>     int head[HASHSZ];
>     // head store the value of id
>     int tot;
>     
>     void init() {
>         Set(head, -1);
>         tot = 0;
>     }
>     
>     void insert(int hashV, int val) {
>         nodes[tot].val = val;
>         nodes[tot].nxt = head[hashV];
>         head[hashV] = tot++;
>     }
>     
>     int find(int dta) {
>         int hashV = dta % HASHSZ;
>         int i;
>         for(i = head[hashV]; ~i; i = nodes[i].nxt) {
>             int val = nodes[i].val;
>             if(val == dta) return i;
>         }
>         insert(hashV, dta);
>         return tot - 1;
>     }
> };
> 
> HASH hashTb;
> void initHash() {
>     hashTb.init();
> }
> 
> bool vis1[maxn], vis2[maxn];
> void initVis() {
>     Set(vis1, 0);
>     Set(vis2, 0);
> }
> 
> class StNode {
> public:
>     int state;
>     int pos;
>     int dist;
>     
>     StNode(int s = 0, int p = 0, int dist = 0) : state(s), pos(p), dist(dist) {}
> };
> 
> const int dx[] = {-1, 0, 1, 0};
> const int dy[] = {0, -1, 0, 1};
> // const int UP = 0, LEFT = 1, DOWN = 2, RIGHT = 3;
> 
> /*
>  if(top == W && face == R) return 1;
>  if(top == W && face == B) return 2;
>  if(top == R && face == W) return 3;
>  if(top == R && face == B) return 4;
>  if(top == B && face == W) return 5;
>  if(top == B && face == R) return 6;
>  */
> 
> // const int Move[0][dir]
> // const int Move[1][dir]
> // UP LEFT DOWN RIGHT
> // Move[1][UP] = (R, W)  Move[1][LEFT] = (B, R) Move[0][DOWN] = (R, W)  Move[0][RIGHT] = (B, R)
> // Move[2][UP] = (B, W)  Move[2][LEFT] = (R, B)
> // Move[3][UP] = (W, R)  Move[3][LEFT] = (B, W)
> // Move[4][UP] = (B, R)  Move[4][LEFT] = (W, B)
> // Move[5][UP] = (W, B)  Move[6][LEFT] = (R, W)
> // Move[6][UP] = (R, B)  Move[6][LEFT] = (W, R)
> 
> const int Move[7][4] = {
>     {0, 0, 0, 0},
>     {3, 6, 3, 6},
>     {5, 4, 5, 4},
>     {1, 5, 1, 5},
>     {6, 2, 6, 2},
>     {2, 3, 2, 3},
>     {4, 1, 4, 1}
> };
> // usage: int newCode = Move[oldCode][dir]
> 
> queue<StNode> que1, que2;
> char tar[11];
> int tep;
> 
> void initQue() {
>     while(!que1.empty()) que1.pop();
>     while(!que2.empty()) que2.pop();
> }
> 
> int getBit(int state, int k) {
>     return ( ( (state >> (3 * k + 2)) & 1 ) << 2 ) |
>            ( ( (state >> (3 * k + 1)) & 1 ) << 1 ) |
>            ( ( (state >> (3 * k)) & 1 ));
> }
> 
> 
> void dfs(int d, int state, int tep) {
>     if(d == 9) {
>         StNode cur(state, tep, 0);
>         que2.push(cur);
>         
>         int dta2 = hashTb.find(state);
>         vis2[dta2] = 1;
>         return;
>     }
>     
>     if(tar[d] == 'E') {
>         dfs(d + 1, state << 3, tep);
>         return;
>     }
>     
>     int v1, v2;
>     if(tar[d] == 'W') {
>         v1 = 1; v2 = 2;
>     }
>     else if(tar[d] == 'R') {
>         v1 = 3; v2 = 4;
>     }
>     else {
>         v1 = 5; v2 = 6;
>     }
>     
>     dfs(d + 1, (state << 3) | v1, tep);
>     dfs(d + 1, (state << 3) | v2, tep);
> }
> 
> // const int UP = 0, LEFT = 1, DOWN = 2, RIGHT = 3;
> inline void update(StNode& u, int dir) {
>     if(dir == 0) {
>         //
>         int np = u.pos - 3;
>         int bit = getBit(u.state, 8 - np);
>         
>         int nbit = Move[bit][dir];
>         u.state = (u.state ^ ( bit << ((8 - np) * 3) )) | ( nbit << ((8 - np - 3) * 3) );
>         u.dist++;
>         u.pos = np;
>     }
>     else if(dir == 1) {
>         int np = u.pos - 1;
>         int bit = getBit(u.state, 8 - np);
>         
>         int nbit = Move[bit][dir];
>         u.state = (u.state ^ ( bit << ((8 - np) * 3) )) | ( nbit << ((8 - np - 1) * 3) );
>         u.dist++;
>         u.pos = np;
>     }
>     else if(dir == 2) {
>         int np = u.pos + 3;
>         int bit = getBit(u.state, 8 - np);
>         
>         int nbit = Move[bit][dir];
>         u.state = (u.state ^ ( bit << ((8 - np) * 3) )) | ( nbit << ((8 - np + 3) * 3) );
>         u.dist++;
>         u.pos = np;
>     }
>     else if(dir == 3) {
>         int np = u.pos + 1;
>         int bit = getBit(u.state, 8 - np);
>         
>         int nbit = Move[bit][dir];
>         u.state = (u.state ^ ( bit << ((8 - np) * 3) )) | ( nbit << ((8 - np + 1) * 3) );
>         u.dist++;
>         u.pos = np;
>     }
> }
> 
> bool valid(int x, int y) {
>     if(0 <= x && x < 3 && 0 <= y && y < 3) return true;
>     return false;
> }
> 
> int bfs() {
>     const int DEP1 = 20, DEP2 = 9;
>     int lv1 = 0, lv2 = 0;
>     
>     for(lv1 = 0; lv1 <= DEP1; lv1++) {
>         while (!que1.empty() && que1.front().dist == lv1) {
>             // do something
>             StNode x = que1.front(); que1.pop();
>             int ex = x.pos / 3, ey = x.pos % 3;
>             _for(dir, 0, 4) {
>                 int nx = ex + dx[dir], ny = ey + dy[dir];
>                 if(!valid(nx, ny)) continue;
>                 
>                 StNode clone = x;
>                 update(clone, dir);
>                 int hashV = hashTb.find(clone.state);
>                 
>                 if(!vis1[hashV]) {
>                     vis1[hashV] = true;
>                     if(vis2[hashV]) return lv1 + lv2 + 1;
>                     que1.push(clone);
>                 }
>             }
>         }
>         
>         while(!que2.empty() && que2.front().dist == lv2 && lv2 < DEP2) {
>             // do something
>             StNode x = que2.front(); que2.pop();
>             int ex = x.pos / 3, ey = x.pos % 3;
>             _for(dir, 0, 4) {
>                 int nx = ex + dx[dir], ny = ey + dy[dir];
>                 if(!valid(nx, ny)) continue;
>                 
>                 StNode clone = x;
>                 update(clone, dir);
>                 int hashV = hashTb.find(clone.state);
>                 
>                 if(!vis2[hashV]) {
>                     vis2[hashV] = true;
>                     if(vis1[hashV]) return lv1 + lv2 + 2;
>                     que2.push(clone);
>                 }
>             }
>         }
>         
>         if(lv2 < DEP2) lv2++;
>     }
>     return -1;
> }
> 
> 
> int main() {
>     //freopen("input.txt", "r", stdin);
>     
>     int ex, ey;
>     while (scanf("%d%d", &ex, &ey) != EOF && ex && ey) {
>         initVis();
>         initQue();
>         initHash();
>         ex--; ey--;
>         int ep = ey * 3 + ex;
>         
>         StNode s(0, ep, 0);
>         _for(i, 0, 9) {
>             s.state <<= 3;
>             if(i == ep) continue;
>             s.state |= 1;
>         }
>         que1.push(s);
>         
>         int dta1 = hashTb.find(s.state);
>         vis1[dta1] = 1;
>         // get start state finished
>         
>         
>         // then get end status
>         char c[3];
>         _for(i, 0, 3) _for(j, 0, 3) {
>             scanf("%s", c);
>             tar[i * 3 + j] = c[0];
>             if(c[0] == 'E') tep = i * 3 + j;
>         }
>         
>         // judge 0
>         int i;
>         for(i = 0; i < 9; i++) {
>             if(tar[i] == 'W' && i != s.pos) continue;
>             if(tar[i] == 'E' && i == s.pos) continue;
>             else break;
>         }
>         if(i == 9) {
>             printf("0\n");
>             continue;
>         }
>         
>         // then add all 256 situation to the end queue
>         dfs(0, 0, tep);
>         // printf("%d\n", que2.size());
>         
>         // then double-way bfs
>         printf("%d\n", bfs());
>     }
> }

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator