UVa 1601 万圣节后的早晨(The morning after Halloween)

该博客探讨了UVa 1601编程题目的解决方案,涉及在w*h网格中移动小写字母至对应大写字母的有向图构建和两种不同的搜索策略——双向BFS与DBFS,这两种方法在UVA在线判题系统上的运行时间分别为1000ms和750ms。
摘要由CSDN通过智能技术生成

题目:
w*h 网格上有n (n<=3) 个小写字母,要求把他们分别移动到对应的大写字母里。每步可以有多个鬼同时移动(往上下左右移动,也可以不动,移动是独立的),每步结束后两个鬼不能占用同一个位置,也不能在一步之内交换位置。

要点:

  • 建立新的有向图

下面给出两种做法,在UVA上分别以 1000ms 和 750ms 左右通过, 双向bfs快了不多。

bfs:

#include<bits/stdc++.h>
#define LL long long
using namespace std;

int s[3], t[3];
int dx[] = {
   0, 1, 0, -1, 0};
int dy[] = {
   1, 0, -1, 0, 0};
int deg[300];
int G[300][300];

struct Node {
   
    int c1, c2, c3; 
};
inline bool confict(int a1, int b1, int a2, int b2) {
   
    return a2 == b2 || (a1 == b2 && b1 == a2);
}
int d[300][300][300];
int bfs() {
   
    memset(d, -1, sizeof(d));
    queue<Node> q;
    Node begin;
    begin.c1 = s[0];
    begin.c2 = s[1];
    begin.c3 = s[2];
    q.push(begin);
    d[s[0]][s[1]][s[2]] = 0;
    while(!q.empty()) {
   
        Node n = q.front();
        q.pop();
        int c1 = n.c1;
        int c2 = n.c2;
        int c3 = n.c3;
        if(c1 == t[0] && c2 == t[1] && c3 == t[2]) return d[c1][c2][c3];
        for(int i = 0; i < deg[c1]; i++) {
   
            int c11 = G[c1][i];
            for(int j = 0; j < deg[c2]; j++) {
   
                int c21 = G[c2][j];
                if(confict(c1, c2, c11, c21)) continue;
                for(int z = 0; z < deg[c3]; z++) {
   
                    int c31 = G[c3][z];
                    if(confict(c1, c3, c11, c31)) continue;
                    if(confict(c2, c3, c21, c31)) continue;
                    if(d[c11][c21][c31] != -1) continue;
                    Node nn;
                    nn.c1 = c11; nn.c2 = c21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值