uva 1533(bfs+状态压缩)
2015-04-22 23:52
323 查看
题意:有一个棋盘如下,黑色表示有棋子,白色表示空,棋盘初始状态为有一个位置n为空,其他位置都有棋子。
每次可以选择一个棋子在一条直线上隔一个或连续多个棋子跳到空白位置,然后这一个或多个棋子就被拿走,问最少几步可以使棋盘上的棋子拿走到只剩下一个且位置和初始空白位置相同。输出几步和每步的起始与落子位置。输出字典序最小的解,无解输出IMPOSSIBLE。
题解:因为棋盘上有15个位置,可以用状态压缩来表示棋盘的状态,1表示有棋子,0表示空白,每个棋子走的方向有6种,所以用一个flag[i][j]数组表示位置i走方向j的位置是什么,然后进行bfs,用异或操作更改棋盘状态。
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
const int N = 15;
int pos, mp[1 << N];
int flag[15][6] = {{-1,-1,-1,-1,2,3},{-1,1,-1,3,4,5},{1,-1,2,-1,5,6},
{-1,2,-1,5,7,8},{2,3,4,6,8,9},{3,-1,5,-1,9,10},
{-1,4,-1,8,11,12},{4,5,7,9,12,13},{5,6,8,10,13,14},
{6,-1,9,-1,14,15},{-1,7,-1,12,-1,-1},{7,8,11,13,-1,-1},
{8,9,12,14,-1,-1},{9,10,13,15,-1,-1},{10,-1,14,-1,-1,-1}};
struct P {
int step;
int path[N + 5][2];
int S;
int num;
};
int bfs(int s) {
queue<P> q;
while (!q.empty())
q.pop();
P a;
a.S = s;
a.num = 1;
a.step = 0;
q.push(a);
while (!q.empty()) {
P u = q.front();
q.pop();
for (int i = 0; i < 15; i++) {
if (u.S & (1 << i)) {
for (int j = 0; j < 6; j++) {
int cur = i;
P b = u;
if (flag[i][j] != -1 && b.S & (1 << (flag[i][j] - 1))) {
while (cur != -1 && b.S & (1 << cur)) {
b.S ^= (1 << cur);
cur = flag[cur][j] - 1;
b.num++;
}
if (cur < 0)
continue;
b.S |= (1 << cur);
b.step = u.step + 1;
b.path[b.step][0] = i;
b.path[b.step][1] = cur;
b.num--;
if (!mp[b.S]) {
if (b.num == 14 && b.S & (1 << (pos - 1))) {
printf("%d\n%d %d", b.step, b.path[1][0] + 1, b.path[1][1] + 1);
for (int k = 2; k <= b.step; k++)
printf(" %d %d", b.path[k][0] + 1, b.path[k][1] + 1);
printf("\n");
return 1;
}
mp[b.S] = 1;
q.push(b);
}
}
}
}
}
}
return 0;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%d", &pos);
memset(mp, 0, sizeof(mp));
int temp = ((1 << 15) - 1) ^ (1 << (pos - 1));
mp[temp] = 1;
int res = bfs(temp);
if (!res)
printf("IMPOSSIBLE\n");
}
return 0;
}
每次可以选择一个棋子在一条直线上隔一个或连续多个棋子跳到空白位置,然后这一个或多个棋子就被拿走,问最少几步可以使棋盘上的棋子拿走到只剩下一个且位置和初始空白位置相同。输出几步和每步的起始与落子位置。输出字典序最小的解,无解输出IMPOSSIBLE。
题解:因为棋盘上有15个位置,可以用状态压缩来表示棋盘的状态,1表示有棋子,0表示空白,每个棋子走的方向有6种,所以用一个flag[i][j]数组表示位置i走方向j的位置是什么,然后进行bfs,用异或操作更改棋盘状态。
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
const int N = 15;
int pos, mp[1 << N];
int flag[15][6] = {{-1,-1,-1,-1,2,3},{-1,1,-1,3,4,5},{1,-1,2,-1,5,6},
{-1,2,-1,5,7,8},{2,3,4,6,8,9},{3,-1,5,-1,9,10},
{-1,4,-1,8,11,12},{4,5,7,9,12,13},{5,6,8,10,13,14},
{6,-1,9,-1,14,15},{-1,7,-1,12,-1,-1},{7,8,11,13,-1,-1},
{8,9,12,14,-1,-1},{9,10,13,15,-1,-1},{10,-1,14,-1,-1,-1}};
struct P {
int step;
int path[N + 5][2];
int S;
int num;
};
int bfs(int s) {
queue<P> q;
while (!q.empty())
q.pop();
P a;
a.S = s;
a.num = 1;
a.step = 0;
q.push(a);
while (!q.empty()) {
P u = q.front();
q.pop();
for (int i = 0; i < 15; i++) {
if (u.S & (1 << i)) {
for (int j = 0; j < 6; j++) {
int cur = i;
P b = u;
if (flag[i][j] != -1 && b.S & (1 << (flag[i][j] - 1))) {
while (cur != -1 && b.S & (1 << cur)) {
b.S ^= (1 << cur);
cur = flag[cur][j] - 1;
b.num++;
}
if (cur < 0)
continue;
b.S |= (1 << cur);
b.step = u.step + 1;
b.path[b.step][0] = i;
b.path[b.step][1] = cur;
b.num--;
if (!mp[b.S]) {
if (b.num == 14 && b.S & (1 << (pos - 1))) {
printf("%d\n%d %d", b.step, b.path[1][0] + 1, b.path[1][1] + 1);
for (int k = 2; k <= b.step; k++)
printf(" %d %d", b.path[k][0] + 1, b.path[k][1] + 1);
printf("\n");
return 1;
}
mp[b.S] = 1;
q.push(b);
}
}
}
}
}
}
return 0;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%d", &pos);
memset(mp, 0, sizeof(mp));
int temp = ((1 << 15) - 1) ^ (1 << (pos - 1));
mp[temp] = 1;
int res = bfs(temp);
if (!res)
printf("IMPOSSIBLE\n");
}
return 0;
}
相关文章推荐
- UVA-1604 Cubic Eight-Puzzle (双向BFS+状态压缩+限制搜索层数)
- UVA-12569 Planning mobile robot on Tree (EASY Version) (BFS+状态压缩)
- uva 1601 poj 3523 Morning after holloween 万圣节后的早晨 (经典搜索,双向bfs+预处理优化+状态压缩位运算)
- UVALive 3956 Key Task (bfs+状态压缩)
- uva 1601 poj 3523 Morning after holloween 万圣节后的早晨 (经典搜索,双向bfs+预处理优化+状态压缩位运算)
- UVA 1533 - Moving Pegs 状态压缩 + bfs
- UVA -12569 (BFS+状态压缩)
- UVa 1533 - Moving Pegs (隐式图搜索 + 状态压缩)
- 【HDU4845】拯救大兵瑞恩(BFS+状态压缩)
- UVA 10944 Nuts for nuts.. (状态压缩dp)
- UVA - 11008 Antimatter Ray Clearcutting 状态压缩
- 胜利大逃亡—bfs+状态压缩
- uva 10817 状态压缩DP
- uva 11008 Antimatter Ray Clearcutting 状态压缩+记忆化搜索
- hdu1429 胜利大逃亡(续) (BFS+简单状态压缩)
- [湖大热身赛]Flip Five(BFS+状态压缩)
- zoj3675 BFS+状态压缩
- poj 1324(BFS+状态压缩)
- UVA1508-Equipment(状态压缩+暴力枚举)
- HDU 4568 Hunter BFS+状态压缩(才13个点)