• [第一场(2)]portal


    题目描述
    这次题目的主角Chell必须解决GLaDOS提出的一个新的难题。Chell现在在一个布局可以表示为N行M列的房间当中,每一个细分的方格中,可以是一下几种情况之一: ·障碍物-墙(表示为‘#’) ·Chell最初始的位置(表示为‘C’) ·Chell必须到达的终点(表示为‘F’) ·空位置(表示为‘.’) Chell手上有一门所谓的“门枪”,这把枪可以在墙上创造一个入口,每次移动时,她可以进行以下操作中的一种操作: ·向上、下、左、右移动到相邻区域(无法移动到有墙的区域) ·如果上、下、左、右方向有一堵墙(不是相邻的上下左右方向),则可以使用“门枪”在墙上创造一个入口,这个入口只能从被激活的这一侧进入,同一时刻最多只可激活两个入口。如果在已经存在两个入口时再激活一个入口,那么,先创建的那个入口就会消失。创造这种入口所消耗的时间可忽略不计,即记为消耗0时间。 ·如果Chell在一个与墙壁相邻的位置,且这个墙面向她的这一侧有一个入口,且现在有两个入口,那么Chell就可以通过这个入口到另一个入口前的一个无障碍位置。此移动持续一个单位时间。 Chell想知道,她最少需要花费多少时间,从起点到终点。 注意:房间两侧总有墙壁,字母‘C’和‘F’只会出现一次。
    输入格式
    第一行输入两个正整数N、M(4≤N,M≤500),表示房间的行列数。 接下来输入一个N行M列的地图,每个格子包含‘C’,‘.’,‘F’,‘#’这四种中的一种字符。
    输出格式
    输出Chell从起点到终点最少需要花费的时间,如果她不能到达终点,则输出“nemoguce”。
    样例
    样例输入1

    4 4

    #.F#
    #C.#

    样例输出1

    2
    样例输入2

    6 8
    ########
    #.##…F#
    #C.##…#
    #…#…#
    #…##
    ########
    样例输出2

    4
    样例输入3

    4 5

    #C#.#
    ###F#

    样例输出3

    nemoguce
    数据范围与提示
    对于样例2,首先在起点的左侧(3,1)和下侧(6,2)建立一个入口,那么,消耗1个单位时间,Chell就可以到达(5,2)。到达(5,2)后,再在右边(5,7)的墙上建立一个入口,此时,存在的两个入口分别在(6,2)和(5,7)这两个位置,再通过1个单位时间到达(5,6)这个位置。同理,在往上(1,6)建立一个入口,再通过入口,从(5,6)到达(2,6),再向右一步到达终点。这当中一共消耗了4个单位时间。

    解题思路

    此题就是走迷宫,只不过在靠墙的地方的时候我们可以四个方向一直走到底。
    我们考虑一个点,它与四个方向的墙的距离我们可以求出来,然后它到四个墙所需时间就是它到离他最近的墙的距离,我们连个边,建个图,进行最短路操作。

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    struct node{
    	int u,v;
    	node(){};
    	node(int U,int V){
    		u = U,v = V;
    	}
    };
    int n,m,s,e,dis[250005];
    char mase[505][505];
    bool vis[250005];
    vector <node>G[250005];
    void spfa(){
    	memset(dis,0x3f,sizeof(dis));
    	dis[s] = 0;
    	queue<int>Q;
    	Q.push(s);
    	vis[s] = 1;
    	while (!Q.empty()){
    		int p = Q.front();
    		Q.pop();
    		vis[p] = 0;
    		int xx = G[p].size();
    		for (int i = 0;i < xx;i ++){
    			int u = G[p][i].u,v = G[p][i].v;
    			if (dis[u] > dis[p] + v){
    				dis[u] = dis[p] + v;
    				if (!vis[u]){
    					Q.push(u);
    					vis[u] = 1;
    				}
    			}
    		}
    	}
    	if (dis[e] == 0x3f3f3f3f)
    		printf("nemoguce
    ");
    	else 	
    		printf("%d",dis[e]);
    }
    int main(){
    	scanf ("%d%d",&n,&m);
    	for (int i = 1;i <= n;i ++){
    		scanf("
    ");
    		for (int j = 1;j <= m;j ++){
    			scanf ("%c",&mase[i][j]);
    			if (mase[i][j] == 'C'){
    				mase[i][j] = '.';
    				s = i * m + j;
    			}
    			if (mase[i][j] == 'F'){
    				mase[i][j] = '.';
    				e = i * m + j;
    			}
    		}
    	}
    	for (int i = 1;i <= n;i ++){
    		for (int j = 1;j <= m;j ++){
    			if (mase[i][j] == '#')
    				continue;
    			if (j + 1 <= m && mase[i][j + 1] != '#'){
    				G[i * m + j].push_back(node(i * m + j + 1,1));
    				G[i * m + j + 1].push_back(node(i * m + j,1));
    			}
    			if (i + 1 <= n && mase[i + 1][j] != '#'){
    				G[(i + 1) * m + j].push_back(node(i * m + j,1));
    				G[i * m + j].push_back(node((i + 1) * m + j,1));
    			}
    			int tot1 = 0,k1 = i - 1;
    			while (mase[k1][j] != '#'){
    				k1 --;
    				tot1 ++;
    			}
    			int tot2 = 0,k2 = i + 1;
    			while (mase[k2][j] != '#'){
    				k2 ++;
    				tot2 ++;
    			}
    			int tot3 = 0,k3 = j - 1;
    			while (mase[i][k3] != '#'){
    				k3 --;
    				tot3 ++;
    			}
    			int tot4 = 0,k4 = j + 1;
    			while (mase[i][k4] != '#'){
    				k4 ++;
    				tot4 ++;
    			}
    			int min_tot = min(tot1,min(tot2,min(tot4,tot3))) + 1;
    			G[i * m + j].push_back(node ((k1 + 1) * m + j,min_tot));
    			G[i * m + j].push_back(node ((k2 - 1) * m + j,min_tot));
    			G[i * m + j].push_back(node (i * m + k3 + 1,min_tot));
    			G[i * m + j].push_back(node(i * m + k4 - 1,min_tot));
    		}
    	}
    	spfa();
    }
    
  • 相关阅读:
    Java正則表達式入门
    Effect of Switchovers, Failovers, and Control File Creation on Backups
    Android 屏幕截图(底层实现方式)
    Java实现奇偶数排序
    Java实现奇偶数排序
    Java实现奇偶数排序
    Java实现找零问题
    Java实现找零问题
    Java实现找零问题
    Java实现找零问题
  • 原文地址:https://www.cnblogs.com/lover-fucker/p/13566660.html
Copyright © 2020-2023  润新知