zoukankan      html  css  js  c++  java
  • Codeforces Gym101518E:The Pharaoh's Curse(BFS + 离散化)

    题目链接

    题意

    给出一个n*m的地图,人的当前位置是'S',还有不超过两个的箱子'X',任意多个按钮'B',不超过100个可以走的点'.',还有一个在边界的出口'E',当且仅当所有的按钮都被箱子盖住的时候,出口才会打开,人才可以走到出口,问最少需要的步数是多少。

    思路

    首先确定是搜索,那么状态表示的话,因为只有两个箱子,所以只要考虑人的位置和两个箱子各自的位置,但是n,m<=50,因此对于一个状态,要用50^6的数组去表示,很明显会爆空间。

    考虑到只有不超过100个可以走的点,加上'X'和'B'和'S'和'E'之后(最多两个箱子,因此最多两个按钮,其余都"impossible"),最多有106个点,所以可以将坐标离散化,这样处理之后,对于一个状态就只要100^3了。

    状态为 vis[人位置][第一个箱子位置][第二个箱子位置]。

    离散化可以直接用一个二维数组标号(我NC用了map,导致跑的好慢)。

    接下来就是BFS部分。

    对于人的下一个位置有三种情况:

    1. 是箱子,那么要考虑箱子的下一个点是否合法,如果合法,那么人前进一格,箱子也前进一格,否则不入队。

    2. 是合法的点,直接走,入队。

    3. 不合法的点,不入队。

    然后当箱子分别在不同的按钮上,并且人在终点就可以跳出BFS了。

    写的又长又臭

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> pii;
    const int INF = 0x3f3f3f3f;
    const int N = 1e5 + 10;
    struct P {
    	int x, y;
    	P () {}
    	P (int _x, int _y) : x(_x), y(_y) {}
    
    	bool operator < (const P &rhs) const {
    		if(x == rhs.x) return y < rhs.y;
    		return x < rhs.x;
    	}
    } box[111*111], but[111*111], st, ed;
    struct ST {
    	int x, y, x1, y1, x2, y2, step;
    	ST () {}
    	ST (int x, int y, int x1, int y1, int x2, int y2, int step) :
    		x(x), y(y), x1(x1), y1(y1), x2(x2), y2(y2), step(step) {}
    };
    char mp[111][111];
    int n, m, ans, cbox, cbut, cnt;
    bool vis[121][121][121];
    map<P, int> ptoi;
    map<int, P> itop;
    queue<ST> que;
    int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1};
    // down, up, right, left
    
    void init() {
    	for(int i = 1; i <= cbox; i++) box[i].x = 0, box[i].y = 0;
    	for(int i = 1; i <= cbut; i++) but[i].x = 0, but[i].y = 0;
    }
    
    int toint(int x, int y) {
    	return ptoi[P(x, y)];
    }
    
    P top(int x) {
    	return itop[x];
    }
    
    int BFS() {
    	memset(vis, false, sizeof(vis));
        int edst = toint(ed.x, ed.y), but1st = toint(but[1].x, but[1].y), but2st = toint(but[2].x, but[2].y);
    //    printf("ansst : %d - %d - %d
    ", edst, but1st, but2st);
        while(!que.empty()) que.pop();
        que.push(ST(st.x, st.y, box[1].x, box[1].y, box[2].x, box[2].y, 0));
        vis[toint(st.x, st.y)][toint(box[1].x, box[1].y)][toint(box[2].x, box[2].y)] = true;
        while(!que.empty()) {
    		ST now = que.front(); que.pop();
            int x = now.x, y = now.y, x1 = now.x1, y1 = now.y1,
    			x2 = now.x2, y2 = now.y2, step = now.step;
            if((cbut == 2 && toint(x, y) == edst && ((but1st == toint(x1, y1) && but2st == toint(x2, y2)) || (but1st == toint(x2, y2) && but2st == toint(x1, y1))))
    			|| (cbut == 1 && toint(x, y) == edst && (but1st == toint(x1, y1) || but1st == toint(x2, y2)))
    				|| (cbut == 0 && toint(x, y) == edst))
    					return step;
    //		printf("point : (%d, %d) - (%d, %d) - (%d, %d) - %d
    ", x, y, x1, y1, x2, y2, step);
    //		printf("st : %d - %d - %d - %d
    
    ", toint(x, y), toint(x1, y1), toint(x2, y2), step);
            for(int i = 0; i < 4; i++) {
    			int nx = x + dx[i], ny = y + dy[i];
    			if((nx < 1 || nx > n || ny < 1 || ny > m || mp[nx][ny] == '#') && mp[nx][ny] != 'E') continue;
                int stst = toint(nx, ny), b1st = toint(x1, y1), b2st = toint(x2, y2);
                if(nx == x1 && ny == y1) {
    				int nx1 = x1 + dx[i], ny1 = y1 + dy[i];
    				if(nx1 < 1 || nx1 > n || ny1 < 1 || ny1 > m || mp[nx1][ny1] == '#' || (nx1 == x2 && ny1 == y2)) continue;
    				if(vis[toint(nx, ny)][toint(nx1, ny1)][toint(x2, y2)]) continue;
    				vis[toint(nx, ny)][toint(nx1, ny1)][toint(x2, y2)] = true;
                    que.push(ST(nx, ny, nx1, ny1, x2, y2, step + 1));
                } else if(nx == x2 && ny == y2) {
    				int nx2 = x2 + dx[i], ny2 = y2 + dy[i];
    				if(nx2 < 1 || nx2 > n || ny2 < 1 || ny2 > m || mp[nx2][ny2] == '#' || (nx2 == x1 && ny2 == y1)) continue;
    				if(vis[toint(nx, ny)][toint(x1, y1)][toint(nx2, ny2)]) continue;
    				vis[toint(nx, ny)][toint(x1, y1)][toint(nx2, ny2)] = true;
                    que.push(ST(nx, ny, x1, y1, nx2, ny2, step + 1));
                } else {
                	if(vis[toint(nx, ny)][toint(x1, y1)][toint(x2, y2)]) continue;
    				vis[toint(nx, ny)][toint(x1, y1)][toint(x2, y2)] = true;
                    que.push(ST(nx, ny, x1, y1, x2, y2, step + 1));
                }
            }
        }
        return -1;
    }
    
    int main() {
        int t; scanf("%d", &t);
        while(t--) {
    		ptoi.clear(); itop.clear();
    		scanf("%d%d", &n, &m);
            cbox = 0, cbut = 0, cnt = 0;
            for(int i = 1; i <= n; i++) {
    			scanf(" %s", mp[i] + 1);
                for(int j = 1; j <= m; j++) {
                    if(mp[i][j] != '#') ptoi[P(i, j)] = ++cnt, itop[cnt] = P(i, j);
    				if(mp[i][j] == 'S') st.x = i, st.y = j;
    				else if(mp[i][j] == 'E') ed.x = i, ed.y = j;
    				else if(mp[i][j] == 'X') box[++cbox].x = i, box[cbox].y = j;
    				else if(mp[i][j] == 'B') but[++cbut].x = i, but[cbut].y = j;
                }
            }
            if(cbut > cbox) { puts("impossible"); init(); continue; }
    //        puts("------begin BFS------");
            ans = BFS();
    		if(~ans) printf("%d
    ", ans);
    		else puts("impossible");
    		init();
        }
    	return 0;
    }
    
    /*
    8
    7 8
    ########
    #..S...#
    #.####.#
    #.#.XB.#
    #.####.#
    #......E
    ########
    7 8
    ########
    #..S...#
    #.####.#
    #.#.BX.#
    #.####.#
    #......E
    ########
    4 8
    ##E#####
    #...####
    #SX.XBB#
    ########
    7 8
    ########
    #...S###
    #.##.###
    #.X.X.B#
    #.##.###
    #....###
    ####E###
    7 8
    ########
    #...S###
    #.##.###
    #.X.XBB#
    #.##.###
    #....###
    ####E###
    7 7
    #######
    #....##
    #.##.##
    #.SXXB#
    #.##.##
    #....##
    #E#####
    6 7
    #######
    ###...#
    ###.#.#
    #S.X..E
    ###B###
    #######
    5 5
    #####
    #BXB#
    #S#XE
    #...#
    #####
    
    ---
    
    im
    10
    19
    23
    24
    19
    im
    */
    
  • 相关阅读:
    oracle取字符串长度的函数length()和hengthb()
    文件操作
    numpy 库使用
    numpy 与 matplotlib 的应用过程
    使用numpy与matplotlib.pyplot画图
    面向对象的解读
    Python PIL
    Note of Jieba
    python 游戏 —— 汉诺塔(Hanoita)
    有进度条圆周率Π计算
  • 原文地址:https://www.cnblogs.com/fightfordream/p/7635430.html
Copyright © 2011-2022 走看看