【TOJ 1661】Solitaire【BFS】

来源:互联网 发布:淘宝活动招商入口 编辑:程序博客网 时间:2024/04/23 20:05

题意:给出棋盘的起始态和终结态,问能否在8步之内使得起始态变成终结态。

思路:简单的搜索题目,关键是如何保存棋盘的状态,我这里是利用了进制压缩进行保存的。

#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std;#define N (1<<24)struct Po {    int x, y;    bool operator<(const Po a) const{        if (x == a.x) return y < a.y;        return x < a.x;    }};struct P {    Po A[4];}s, e;queue<P>Q;queue<int>step;bool F[10][10];bool flag[N+10];int ci[8], end, go[4][2] = {1,0, -1,0, 0,1, 0,-1};int mark[8][8];int tr(P a) {    int re = 0, i;    sort(a.A, a.A+4);    for (i = 0;i < 4;i++) {        re += a.A[i].x*ci[i*2]+a.A[i].y*ci[i*2+1];    }    return re;}bool ch(int x, int y) {    return x < 0 || x >= 8 || y < 0 || y >= 8;}bool bfs() {    while (!Q.empty()) Q.pop();    while (!step.empty()) step.pop();    memset(flag, false, sizeof(flag));    Q.push(s);    step.push(0);    flag[tr(s)] = true;    int st, i, j, tx, ty, ca = 1, tt;    P v;    memset(mark, 0, sizeof(mark));    while (!Q.empty()) {        v = Q.front();        tt = step.front();        step.pop();        Q.pop();        st = tr(v);        if (st == end) return true;        if (tt == 8) continue;        ca++;        for (i = 0;i < 4;i++) {            mark[v.A[i].x][v.A[i].y] = ca;        }        for (i = 0;i < 4;i++) {            for (j = 0;j < 4;j++) {                tx = v.A[i].x+go[j][0], ty = v.A[i].y+go[j][1];                if (ch(tx, ty)) continue;                P tm = v;                if (mark[tx][ty] != ca) {                    tm.A[i].x = tx, tm.A[i].y = ty;                }else {                    tx += go[j][0], ty += go[j][1];                    if (ch(tx, ty) || mark[tx][ty] == ca) continue;                    tm.A[i].x = tx, tm.A[i].y = ty;                }                int tmst = tr(tm);                if (flag[tmst]) continue;                Q.push(tm), step.push(tt+1), flag[tmst] = true;            }        }    }    return false;}int main() {    int i, j, x, y;    ci[0] = 1;    for (i = 1;i < 8;i++) ci[i] = ci[i-1]*8;    while (~scanf("%d%d", &s.A[0].x, &s.A[0].y)) {        memset(F, false, sizeof(F));        for (i = 1;i < 4;i++) {            scanf("%d%d", &s.A[i].x, &s.A[i].y);        }        for (i = 0;i < 4;i++) s.A[i].x--, s.A[i].y--;        for (i = 0;i < 4;i++) {            scanf("%d%d", &x, &y);            e.A[i].x = x-1, e.A[i].y = y-1;        }        end = tr(e);        if (bfs()) puts("YES");        else puts("NO");    }}


0 0