• 洛谷 P3818 小A和uim之大逃离 II


    洛谷 P3818 小A和uim之大逃离 II

    洛谷传送门

    题目背景

    话说上回……还是参见 https://www.luogu.com.cn/problem/P1373

    小 a 和 uim 再次来到雨林中探险。突然一阵南风吹来,一片乌云从南部天边急涌过来,还伴着一道道闪电,一阵阵雷声。刹那间,狂风大作,乌云布满了天空,紧接着豆大的雨点从天空中打落下来,只见前方出现了一个牛头马面的怪物,低沉着声音说:“呵呵,既然你们来到这,两个都别活了!”。小 a 和他的小伙伴再次惊呆了!

    题目描述

    瞬间,地面上出现了一个 HH 行 WW 列的巨幅矩阵,矩阵的每个格子上要么是空地 . 或者障碍 #

    他们起点在 (1,1)(1,1),要逃往 (H,W)(H,W) 的出口。他们可以一次向上下左右移动一格,这个算一步操作。不过他们还保留着上次冒险时收集的魔液,一口气喝掉后可以瞬移到相对自己位置的 (D,R)(D,R) 向量;也就是说,原来的位置是 (x,y)(x,y),然后新的位置是 (x+D,y+R)(x+D,y+R),这个也算一步操作,不过他们仅能至多进行一次这种操作(当然可以不喝魔液)。

    这个地方是个是非之地。所以他们希望知道最小能有几步操作可以离开这个鬼地方。不过他们可能逃不出这个鬼地方,遇到这种情况,只能等死,别无他法。

    输入格式

    第一行个整数,H,W,D,RH,W,D,R,意义在描述已经说明。

    接下来 HH 行,每行长度是 WW,仅有 . 或者 # 的字符串。

    输出格式

    请输出一个整数表示最小的逃出操作次数。如果他们逃不出来,就输出 -1−1。


    题解:

    2020.11.14模拟赛T2 95分场。

    作法假了...挂了一个点。命好。

    我的思路是:裸的走地图BFS是四种方向搜。这个就变成五种方向就行。

    但是假了。为什么呢?因为喝药有两种作用,如果不喝药能到,喝药使得步数更少。如果不喝药到不了,喝药使穿墙。所以要分两个部分分别搜索转移。

    80pts代码:

    #include<cstdio>
    #include<queue>
    using namespace std;
    const int maxn=1010;
    int n,m,d,r;
    char mp[maxn][maxn];
    bool vis[maxn][maxn];
    int dis[maxn][maxn];
    int dx[]={0,0,0,-1,1,0};
    int dy[]={0,1,-1,0,0,0};
    struct node
    {
    	int x,y,d;
    	bool f;
    };
    queue<node> q;
    int main()
    {
    	// freopen("shadow.in","r",stdin);
    	// freopen("shadow.out","w",stdout);
    	scanf("%d%d%d%d",&n,&m,&d,&r);
    	dx[5]=d;
    	dy[5]=r;
    	for(int i=1;i<=n;i++)
    		scanf("%s",mp[i]+1);
    	if(mp[1][1]=='#')
    	{
    		puts("-1");
    		return 0;
    	}
    	node a;
    	a.x=1,a.y=1,a.d=0,a.f=0;
    	q.push(a);
    	vis[1][1]=1;
    	while(!q.empty())
    	{
    		node u=q.front();
    		q.pop();
    		if(u.x==n && u.y==m)
    		{
    			printf("%d
    ",u.d);
    			return 0;
    		}
    		node v;
    		for(int i=1;i<=5;i++)
    		{
    			v.x=u.x+dx[i];
    			v.y=u.y+dy[i];
    			v.d=u.d+1;
    			v.f=u.f;
    			if(v.x<1 || v.y<1 || v.x>n || v.y>m || mp[v.x][v.y]=='#' || vis[v.x][v.y] || (i==5 && v.f))
    				continue;
    			if(i==5)
    				v.f=1;
    			q.push(v);
    			vis[v.x][v.y]=1;
    		}
    	}
    	puts("-1");
    	return 0;
    }
    

    满分代码:

    #include <bits/stdc++.h>
    #define X x + movx[i]
    #define Y y + movy[i]
    using namespace std;
    bool mapp[2001][2001];
    int movx[4] = {1, 0, -1, 0};
    int movy[4] = {0, 1, 0, -1};
    int n, m;
    int a[2001][2001], b[2001][2001];
    bool used[2001][2001];
    struct hehe{
        int x, y;
    };
    void bfs1()
    {
        queue < hehe >q;
        hehe now;
        now.x = now.y = 1;
        memset(a, 0x3f, sizeof a);
        a[1][1] = 0;
        q.push(now);
        while(q.size())
        {
            now = q.front();
            q.pop();
            int x = now.x, y = now.y;
            used[x][y] = 0;
            for(int i = 0; i < 4; i++)
            {
                if(mapp[X][Y] && a[x][y] + 1 < a[X][Y])
                {
                    a[X][Y] = a[x][y] + 1;
                    if(!used[X][Y])
                    {
                        hehe neww;
                        neww.x = X, neww.y = Y;
                        q.push(neww);
                        used[X][Y] = 1;
                    }
                }
            }
        }
    }
    void bfs2()
    {
        queue < hehe >q;
        hehe now;
        now.x = n;
        now.y = m;
        memset(b, 0x3f, sizeof b);
        memset(used, 0, sizeof used);
        b[n][m] = 0;
        q.push(now);
        while(q.size())
        {
            now = q.front();
            q.pop();
            int x = now.x, y = now.y;
            used[x][y] = 0;
            for(int i = 0; i < 4; i++)
            {
                if(mapp[X][Y] && b[x][y] + 1 < b[X][Y])
                {
                    b[X][Y] = b[x][y] + 1;
                    if(!used[X][Y])
                    {
                        hehe neww;
                        neww.x = X, neww.y = Y;
                        q.push(neww);
                        used[X][Y] = 1;
                    }
                }
            }
        }
    }
    int main()
    {
        int e, r;
        cin >> n >> m >> e >> r;
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= m; j++)
            {
                char ch;
                cin >> ch;
                mapp[i][j] = (ch == '.');
            }
        }
        bfs1();
        bfs2();
        int ans = a[n][m];
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= m; j++)
            {
                if(a[i][j] <= 1000000 && i + e >= 0 && j + r >= 0 && b[i + e][j + r] <= 1000000 && mapp[i + e][j + r])
                    ans = min(ans, a[i][j] + b[i + e][j + r] + 1);
            }
        }
        if(ans > 1000000 || !mapp[n][m]) cout << -1;
        else cout << ans;
        return 0;
    }
    
  • 相关阅读:
    课后作业-阅读任务-阅读提问-3
    《团对-团队编程项目作业名称-开发环境搭建过程》
    《结对贪吃蛇游戏——测试过程》
    《Android手机便签-项目进度》
    结对编程项目作业2-开发环境搭建过程
    结对编程项目作业2-结对编项目设计文档
    《GIT的使用方法》
    课后作业-阅读任务-阅读提问-1
    个人编程项目
    《自我介绍》
  • 原文地址:https://www.cnblogs.com/fusiwei/p/13973206.html
Copyright © 2020-2023  润新知