跳棋+黑白棋,模拟大法好
这次的码写的挺丑的,而且速度也很慢,只是摸爬滚打刚刚够AC
Rujia说第七章的习题想达到更好的效果要做10道,现在做了8道。其实中途还做了其他的,但是最终都没能做完或者AC掉
虽然心有不甘,但是毕竟时间有限。。现在只想快点进入第八章,dp和图论还在等着我。。
Run Time: 1.202s
#define UVa "7-12.1533.cpp"
#include<cstring>
#include<cstdlib>
#include<cstdio>
using namespace std;
//Global Variables. Reset upon Each Case!
int board;
int hole;
const int adj[15][4][6] =
{
{{1,2},{3,5},{6,9},{10,14}},
{{0,2,3,4},{-1,-1,6,8},{-1,-1,10,13}},
{{0,1,4,5},{-1,-1,7,9},{-1,-1,11,14}},
{{1,4,6,7},{0,5,10,12}},
{{1,2,3,5,7,8},{-1,-1,-1,-1,11,13}},
{{2,4,8,9},{0,3,12,14}},
{{3,7,10,11},{1,8,-1,-1},{0,9,-1,-1}},
{{3,4,6,8,11,12},{-1,2,-1,9,-1,-1}},
{{4,5,7,9,12,13},{1,-1,6,-1,-1,-1}},
{{5,8,13,14},{2,7,-1,-1},{0,6,-1,-1}},
{{6,11},{3,12},{1,13},{0,14}},
{{6,7,10,12},{-1,4,-1,13},{-1,2,-1,14}},
{{7,8,11,13},{3,5,10,14}},
{{8,9,12,14},{4,-1,11,-1},{1,-1,10,-1}},
{{9,13},{5,12},{2,11},{0,10}}
};
const int adj_depth[15] = {4,3,3,2,2,2,3,2,2,3,4,3,2,3,4};
const int adj_size[15] = {2, 4, 4, 4, 6, 4, 4, 6, 6, 4, 2, 4, 4, 4, 2};
const int maxstate = 1<<15+10;
int vis[maxstate];
int q[maxstate], d[maxstate], fa[maxstate], act[maxstate][2];
/////
int getDepthPos(int src, int targ, int& d, int& p) {
for(int i = 0; i < adj_depth[src]; i ++) {
for(int j = 0; j < adj_size[src]; j ++) {
if(adj[src][i][j] == targ) {
d = i; p = j;
return 1;
}
}
}
return 0;
}
int movable(int b, int peg, int targdepth, int targpos) {
for(int i = 0; i < targdepth; i ++) { //before arrival, there should be no holes.
if(adj[peg][i][targpos] == -1 || !(b & (1<<adj[peg][i][targpos])) )return 0;
}
if(!(b & (1<<adj[peg][targdepth][targpos]))) {
return 1;
}
return 0;
}
int move(int& b, int peg, int targdepth, int targpos) {
b -= 1<<peg;
for(int i = 0; i < targdepth; i ++) {
b -= 1<<adj[peg][i][targpos]; //set to 0 for the positions along the path;
}
b |= 1<<adj[peg][targdepth][targpos];
return 1;
}
void print_ans(int u) {
if(fa[u] && fa[u] != 1) {
print_ans(fa[u]);
printf(" ");
}
printf("%d %d", act[u][0]+1, act[u][1]+1);
}
int bfs() {
int front = 1, rear = 2;
fa[front] = 0;
d[front] = 0;
q[front] = board;
memset(vis, 0, sizeof(vis));
vis[board] = 1;
while(front < rear) {
int b = q[front];
if(b == (1<<(hole))){
printf("%d\n", d[front]);
print_ans(front);
printf("\n");
return 1;
}
for(int i = 0; i < 15; i ++) if(b & (1<<i)){ //if there's a peg on the position.
for(int j = 0; j < 15; j ++) if(!(b & (1<<j))){ //found a hole. (i != j for sure)
int vd, vp;
if(getDepthPos(i, j, vd, vp)) if(movable(b, i, vd, vp) && vd){ //
int v = b;
move(v, i, vd, vp);
if(!vis[v]){
vis[v] = 1;
q[rear] = v;
act[rear][0] = i;
act[rear][1] = j;
fa[rear] = front;
d[rear++] = d[front] + 1;
}
}
}
}
front ++;
}
return 0;
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
scanf("%d", &hole);
hole --;
board = (1<<15) - 1;
board ^= (1<<hole);
if(!bfs()) printf("IMPOSSIBLE\n");
}
return 0;
}