| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
优化编码 + 双向bfs//
// 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: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator