POJ 1361 Holedox Moving

POJ 1361 Holedox Moving

1 算法

记录蛇头位置后,蛇的身体每一格的前一格对当前个而言只有4种可能,即上左下右,可用2bits进行存储,那么8格长的蛇只需要14bits。

2 代码

2.1 AC的代码

#include <queue>
#include <iostream>
#include <cstring>
using namespace std;
bool isv[20][20][(1 << 14) - 1];

struct node
{
        int bx, by, lx, ly, pos;
        int cost;
};

int n, m, l;
int bx, by, lx, ly, pos0;
int ones;
bool isused[20][20];
int offsetx[4] = {-1, 0, 1, 0};
int offsety[4] = {0, 1, 0, -1};

void read_data()
{
        int fx, fy, px, py;
        int x;
        ones = (1 << (2 * (l - 1))) - 1;
        memset(isused, 0, sizeof(isused));
        cin >> bx >> by;
        bx--;
        by--;
        fx = bx;
        fy = by;
        pos0 = 0;
        for (int i = 1; i < l; ++i)
        {
                cin >> px >> py;
                px--;
                py--;
                if (fx == px - 1)
                        x = 0;
                if (fy == py + 1)
                        x = 1;
                if (fx == px + 1)
                        x = 2;
                if (fy == py - 1)
                        x = 3;
                pos0 += x << ((i - 1) * 2);
                fx = px;
                fy = py;
        }
        cin >> x;
        while (x--)
        {
                cin >> px >> py;
                px--;
                py--;
                isused[px][py] = true;
        }
        lx = fx;
        ly = fy;
}

bool isinside(int x, int y)
{
        return (0 <= x && x < n && 0 <= y && y < m);
}

void get_newl(int lx, int ly, int &newlx, int &newly, int pos)
{
        newlx = lx + offsetx[(pos >> ((l - 2) * 2))];
        newly = ly + offsety[(pos >> ((l - 2) * 2))];
}

void dealused(int lx, int ly, int pos, bool val)
{
        isused[lx][ly] = val;
        for (int i = (l - 2) * 2; i >= 0; i = i - 2)
        {
                lx = lx + offsetx[(pos >> i) & 3];
                ly = ly + offsety[(pos >> i) & 3];
                isused[lx][ly] = val;
        }
}
int bfs()
{
        struct node temp;
        struct node tempnext;
        int x, y;
        queue<struct node=""> q;
        if (bx == 0 && by == 0) return 0;
        memset(isv, 0, sizeof(isv));
        temp.bx = bx;
        temp.by = by;
        temp.lx = lx;
        temp.ly = ly;
        temp.pos = pos0;
        temp.cost = 0;
        isv[bx][by][pos0] = true;
        q.push(temp);
        while (!q.empty())
        {
                temp = q.front();
                dealused(temp.lx, temp.ly, temp.pos, true);
                //cout << temp.pos << ' ' << temp.cost <<endl;
                for (int i = 0; i < 4; ++i)
                {
                        tempnext.bx = temp.bx + offsetx[i];
                        tempnext.by = temp.by + offsety[i];
                        tempnext.pos = ((temp.pos << 2) + i) & ones;
                        if (isinside(tempnext.bx, tempnext.by) && !isused[tempnext.bx][tempnext.by] 
                                        && !isv[tempnext.bx][tempnext.by][tempnext.pos])
                        {
                                if (tempnext.bx == 0 && tempnext.by == 0) return temp.cost + 1;
                                get_newl(temp.lx, temp.ly, tempnext.lx, tempnext.ly, temp.pos);
                                tempnext.cost = temp.cost + 1;
                                q.push(tempnext);
                                isv[tempnext.bx][tempnext.by][tempnext.pos] = true;
                        }
                }
                dealused(temp.lx, temp.ly, temp.pos, false);
                q.pop();
        }
        return -1;
}
                        

int main()
{
        int counter = 0;
        cin >> n >> m >> l;
        while (n != 0 && m != 0 && l != 0)
        {
                read_data();
                counter++;
                cout << "Case " << counter << ": " << bfs() << endl;
                cin >> n >> m >> l;
        }
        return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值