UVa1533 - Moving Pegs(错在什么地方)

#include <iostream>
#include <fstream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 5;
const int M = 100;
const int HASHSIZE = 10000007;
const int QUEUELEN = 100000;

struct Node {
    int step;
    int m[N][N];
    int ans[M];
};

int src[N][N];
int m;
int head[HASHSIZE];
int next[QUEUELEN];
Node q[QUEUELEN];

void bfs();
int hash(Node node);
int insert(int v);
bool check(Node node);
void print(Node node);

int main()
{
    int t;
    int count;

    #ifndef ONLINE_JUDGE
        ifstream cin("d:\\OJ\\uva_in.txt");
    #endif // ONLINE_JUDGE

    cin >> t;


    while (t--) {
        memset(src, 0x00, sizeof(src));
        cin >> m;
        if (m < 1 && m > 15 ) {
            cout << "IMPOSSIBLE" << endl;
            continue;
        }
        count = 1;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j <= i; j++) {
                if (count != m)
                    src[i][j] = count;
                count++;
            }
        }
        bfs();
    }
    return 0;
}

void bfs()
{
    int front = 0, rear = 0;
    Node node, newNode;
    bool flag;
    int step;

    memset(&node, 0x00, sizeof(Node));
    memset(head, -1, sizeof(head));
    memcpy(node.m, src, sizeof(src));

    q[rear++] = node;


    while (front < rear) {
        Node tmp = q[front++];
        if (check(tmp)) {
            int step = tmp.step;
            cout << step << endl;
            for (int i = 0; i < step; i++) {
                if (i)
                    cout << " ";
                cout << tmp.ans[2 * i] << " " << tmp.ans[2 * i + 1];
            }
            cout << endl;
            return;
        }
        for (int i = 0; i < N; i++) {
            for (int j = 0; j <= i; j++) {
                if (tmp.m[i][j] == 0) {
                    //水平方向
                    flag = true;
                    int jj = j + 1;
                    if (jj > i)
                        flag = false;

                    if (flag && tmp.m[i][jj] == 0)
                        flag = false;

                    while (flag && jj <= i && tmp.m[i][jj] != 0) {
                        if (jj - j >= 2) {
                            newNode = tmp;
                            swap(newNode.m[i][jj], newNode.m[i][j]);
                            fill(&(newNode.m[i][j + 1]), &(newNode.m[i][jj]), 0x00);
                            step = newNode.step;
                            newNode.ans[2 * step] = (i + 1) * i / 2 + jj + 1;
                            newNode.ans[2 * step + 1] = (i + 1) * i / 2 + j + 1;
                            newNode.step++;
                            q[rear] = newNode;
                            if (insert(rear)) rear++;
                        }
                        jj++;
                    }
                    if (flag && jj - 1 - j < 2)
                        flag = false;;

                    if (flag ) {
                        newNode = tmp;
                        swap(newNode.m[i][j], newNode.m[i][jj - 1]);
                        fill(&(newNode.m[i][j + 1]), &(newNode.m[i][jj]), 0x00);
                        step = newNode.step;
                        newNode.ans[2 * step] = (i + 1) * i / 2 + jj;
                        newNode.ans[2 * step + 1] = (i + 1) * i / 2 + j + 1;
                        newNode.step++;

                        q[rear] = newNode;


                        if (insert(rear)) rear++;
                    }

                    //竖直方向
                    flag = true;
                    int ii = i + 1;
                    //cout << "ii1:" << ii << endl;
                    if (ii >= N)
                        flag = false;

                    if (flag && tmp.m[ii][j] == 0)
                        flag = false;;

                    while (flag && ii < N && tmp.m[ii][j] != 0) {
                        if (ii - i >= 2) {
                            newNode = tmp;
                            swap(newNode.m[i][j], newNode.m[ii][j]);
                            for (int k = i + 1; k < ii; k++) {
                                newNode.m[k][j] = 0;
                            }
                            step = newNode.step;
                            newNode.ans[2 * step] = (ii + 1) * ii / 2 + j + 1;
                            newNode.ans[2 * step + 1] = (i + 1) * i / 2 + j + 1;
                            newNode.step++;
                            q[rear] = newNode;
                            if (insert(rear)) rear++;
                        }
                        ii++;
                    }
                    ii--;

                    if (flag && ii - i < 2)
                        flag = false;

                    if (flag) {
                        newNode = tmp;
                        swap(newNode.m[i][j], newNode.m[ii][j]);
                        for (int k = i + 1; k < ii; k++)
                            newNode.m[k][j] = 0;
                        step = newNode.step;
                        newNode.ans[2 * step] = (ii + 1) * ii / 2 + j + 1;
                        newNode.ans[2 * step + 1] = (i + 1) * i / 2 + j + 1;
                        newNode.step++;

                        q[rear] = newNode;
                        if (insert(rear)) rear++;
                    }

                    //对角线方向
                    flag = true;
                    ii = i + 1;
                    jj = j + 1;
                    if (ii >= N)
                        flag = false;

                    if (flag && tmp.m[ii][jj] == 0)
                        flag = false;

                    while (flag &&ii < N && tmp.m[ii][jj] != 0) {
                        if (ii - i >= 2) {
                            newNode = tmp;
                            swap(newNode.m[i][j], newNode.m[ii][jj]);
                            for (int k = i + 1, p = j + 1; k < ii; k++, p++) {
                                newNode.m[k][p] = 0;
                            }
                            step = newNode.step;
                            newNode.ans[2 * step] = (ii + 1) * ii / 2 + jj + 1;
                            newNode.ans[2 * step + 1] = (i + 1) * i / 2 + j + 1;
                            newNode.step++;

                            q[rear] = newNode;
                            if (insert(rear)) rear++;
                        }
                        ii++, jj++;
                    }

                    ii--, jj--;
                    if (flag && ii - i < 2)
                        flag = false;

                    if (flag) {
                        newNode = tmp;
                        swap(newNode.m[i][j], newNode.m[ii][jj]);
                        for (int k = i + 1, p = j + 1; k < ii; k++, p++)
                            newNode.m[k][p] = 0;
                        step = newNode.step;
                        newNode.ans[2 * step] = (ii + 1) * ii / 2 + jj + 1;
                        newNode.ans[2 * step + 1] = (i + 1) * i / 2 + j + 1;
                        newNode.step++;

                        q[rear] = newNode;
                        if (insert(rear)) rear++;


                    }

                } else {
                    //水平方向
                    flag = true;
                    int jj = j + 1;
                    if (jj > i)
                        flag = false;;


                    if (flag && tmp.m[i][jj] == 0)
                        flag = false;

                    while (flag && jj <= i && tmp.m[i][jj] != 0) jj++;
                    if (flag && jj > i)
                        flag = false;

                    if (flag && jj - j < 2)
                        flag = false;

                    if (flag) {
                        newNode = tmp;
                        swap(newNode.m[i][j], newNode.m[i][jj]);
                        fill(&newNode.m[i][j + 1], &newNode.m[i][jj], 0x00);
                        int step = newNode.step;
                        newNode.ans[2 * step] = (i + 1) * i / 2 + j + 1;
                        newNode.ans[2 * step + 1] = (i + 1) * i / 2 + jj + 1;
                        newNode.step++;

                        q[rear] = newNode;
                        if (insert(rear)) rear++;
                    }

                    //竖直方向
                    flag = true;
                    int ii = i + 1;
                    if (ii >= N)
                        flag = false;

                    if (flag && tmp.m[ii][j] == 0)
                        flag = false;

                    while (flag && ii < N && tmp.m[ii][j] != 0) ii++;
                    if (flag && ii >= N)
                        flag = false;

                    if (flag && ii - i < 2)
                        flag = false;

                    if (flag) {
                        newNode = tmp;
                        swap(newNode.m[i][j], newNode.m[ii][j]);
                        for (int k = i + 1; k < ii; k++)
                            newNode.m[k][j] = 0;
                        step = newNode.step;
                        newNode.ans[2 * step] = (i + 1) * i / 2 + j + 1;
                        newNode.ans[2 * step + 1] = (ii + 1) * ii / 2 + j + 1;
                        newNode.step++;

                        q[rear] = newNode;
                        if (insert(rear)) rear++;
                    }


                    //对角线方向
                    flag = true;
                    ii = i + 1;
                    jj = j + 1;
                    if (ii >= N)
                        flag = false;

                    if (flag && tmp.m[ii][jj] == 0)
                        flag = false;

                    while (flag && ii < N && tmp.m[ii][jj] != 0) ii++, jj++;
                    if (flag && ii >= N)
                        flag = false;

                    if (flag && ii - i < 2)
                        flag = false;

                    if (flag ) {
                        newNode = tmp;
                        swap(newNode.m[i][j], newNode.m[ii][jj]);
                        for (int k = i + 1, p = j + 1; k < ii; k++, p++)
                            newNode.m[k][p] = 0;
                        step = newNode.step;
                        newNode.ans[2 * step] = (i + 1) * i / 2 + j + 1;
                        newNode.ans[2 * step + 1] = (ii + 1) * ii / 2 + jj + 1;
                        newNode.step++;

                        q[rear] = newNode;
                        if (insert(rear)) rear++;
                    }
                }
            }
        }

    }

    cout << "IMPOSSIBLE" <<  endl;
}

int hash(Node node)
{
    int h = 0;

    for (int i = 0; i < 5; i++) {
        for (int j = 0; j <= i; j++) {
            h = h * 10 + node.m[i][j];
        }
    }

    return (h & 0x7fffffff) % HASHSIZE;
}

int insert(int v)
{
    int h = hash(q[v]);

    for (int u = head[h]; u != -1; u = next[u])
        if (memcmp(q[u].m, q[v].m, sizeof(src)) == 0)
            return 0;

    next[v] = head[h];
    head[h] = v;

    return 1;
}

bool check(Node node)
{
    int count = 1;
    int cx, cy;

    for (int i = 0; i < N; i++) {
        for (int j = 0; j <= i; j++) {
            if (count != m) {
                if (node.m[i][j] != 0)
                    return false;
            } else {
                cx = i;
                cy = j;
            }
            count++;
        }
    }

    return node.m[cx][cy] != 0;

}


void print(Node node)
{
    for (int i = 0; i < N; i++) {
        for (int j = 0; j <= i; j++) {
            cout << node.m[i][j] << " ";
        }
        cout << endl;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值