您的位置:首页 > 其它

UVA 1533 - Moving Pegs 状态压缩 + bfs

2015-04-20 23:41 344 查看
这题需要注意的是 当一个球的相邻位置为空时 不能直接跳过去 之间必须要有球垫着

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

#define bug puts("bug")

const int link[15][6] = { {-1,-1,-1,-1, 1, 2},  {-1, 0,-1, 2, 3, 4},  { 0,-1, 1,-1, 4, 5},  {-1, 1,-1, 4, 6, 7},
{ 1, 2, 3, 5, 7, 8},  { 2,-1, 4,-1, 8, 9},  {-1, 3,-1, 7,10,11},  { 3, 4, 6, 8,11,12},
{ 4, 5, 7, 9,12,13},  { 5,-1, 8,-1,13,14},  {-1, 6,-1,11,-1,-1},  { 6, 7,10,12,-1,-1},
{ 7, 8,11,13,-1,-1},  { 8, 9,12,14,-1,-1},  { 9,-1,13,-1,-1,-1} };

struct Node{
int g;   // 0 represent empty and 1 represent full
int step;
int num;
Node(int g = 0, int step = 0, int num = 0) : g(g), step(step), num(num){}
};

struct Path{
int u, v;
Path(int u = 0, int v = 0) : u(u), v(v){}
};

const int maxn = 16;

int n, cnt, k;
int fa[1 << maxn];
bool vis[1 << maxn];
Path path[1 << maxn];
Node S;

void print(int c){
if(fa[c] == -1) return;
print(fa[c]);
if(c == k) printf("%d %d\n", path[c].u + 1, path[c].v + 1);
else printf("%d %d ", path[c].u + 1, path[c].v + 1);
}

int bfs(){
queue<Node> Q;
Q.push(S);
vis[Q.front().g] = true;
while(!Q.empty()){
//            bug;
Node cur = Q.front(); Q.pop();
if(cur.g == (1 << n)){
k = cur.num;
return cur.step;
}
for(int i = 0; i < 15; i++)if((1 << i) & cur.g){ //if full

for(int j = 0; j < 6; j++){
int x = (1 << i);
int st = 0;
int go = link[i][j];
while(go != -1){ // find empty
if(!((1 << go) & cur.g)){
if(!st) break;
Node tmp;
x ^= cur.g;
x |= (1 << go);
tmp.g = x;
tmp.step = cur.step+1;

if(!vis[x]){
vis[x] = true;
tmp.num = ++cnt;
fa[cnt] = cur.num;
path[cnt] = Path(i, go);
Q.push(tmp);

}
break;
}
x |= (1 << go); // save
go = link[go][j];
st++;
}
}
}
}
return -1;
}

int main()
{
int T;
scanf("%d", &T);
while(T--){
scanf("%d", &n);
memset(vis, false, sizeof(vis));
n--;
int g = 0;
for(int i = 0; i < 15; i++){
if(i != n)
g |= (1 << i);
}
S.g = g;
S.step = 0;
S.num = cnt = 0;
fa[0] = -1;
int ans = bfs();

if(ans == -1){
printf("IMPOSSIBLE\n");
}
else{
printf("%d\n", ans);
print(k);
}

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: