zoukankan      html  css  js  c++  java
  • nyoj 999 师傅又被妖怪抓走了

    师傅又被妖怪抓走了

    时间限制:1000 ms  |  内存限制:65535 KB

    难度:3

    描述

    话说唐僧复得了孙行者,师徒们一心同体,共诣西方。自宝象国救了公主,承君臣送出城西,沿路饥餐渴饮,悟空便为师傅去化斋,等悟空回来,悟净慌慌张张的对悟空说:“不好了,不好了”,还没等悟净说完,悟空说:“师傅又被妖怪抓走了”,悟净:“NO” ,悟空一脸茫然,悟净:“师傅和二师兄都被妖怪抓走了”。悟空(晕!)。为了防止悟空救人,妖怪先把唐憎和八戒分别藏起来,如果悟空在T分钟之后还没找到人,那必定是被妖怪吃掉了。假设悟空在一个nm列的矩阵内,悟空在每一分钟可以走到上,下,左,右的其中的一个可以走的位置,每次只能走一步。我们把发现定义为可以直接看到对方,也就是说两个人在同一行或者同一列,并且中间没有障碍物或者没有其他人就可以看到对方。

    输入

    有多组测试数据,每组首先是三个正整数n , m (3<=n,m<=100), T,(0<=T<=100) 分别代表行数,列数,规定的时间。接下来n 行,每行 m 个字符。其中’ S ’ 代表悟空的位置,’ D ’代表师傅位置,’ E ’代表八戒的位置。并且保证都只有一个. ’ X ’代表墙 ,’ . ’代表空地 .

    输出

    每组先输出一行Case c:(c表示当前的组数,从1开始计数);
    接下来一行,如果悟空可以在规定时间内找到两人,则输出最少需要的时间,否则输出-1。

    样例输入

    5 6 3

    XXD...

    ....E.

    ....X.

    ....S.

    ......

    5 6 3

    XDX...

    ....E.

    ......

    ....S.

    ......

    5 6 8

    XXDX..

    .XEX..

    ......

    ....S.

    ......

    样例输出

    Case 1:

    -1

    Case 2:

    3

    Case 3:

    -1

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<iostream>
    using namespace std;
    
    int dir[4][2]={-1,0,1,0,0,-1,0,1};
    int visit[105][105][4];
    char map[105][105];
    int n,m,t,ans;
    
    struct Node{
    	int x,y;
    	int step,st;
    };
    
    
    //状态压缩,将D点和E点所在的行列的‘.’扩展为d和e,
    
    
    //	把师傅所在行和列标记为 1 状态   'd'
    //	二师兄所在行和列标记为 2 状态   'e'
    //	如果师傅和二师兄在同一行或同一列,重合的部分标记为3状态 'x'
    
    //	要想把师傅和二师兄都找到:
    //		要么先找到师傅,再找到二师兄;
    //  	要么先找到二师兄,再找到师傅;
    //		要么同时找到
    
    
    int ST_solve(char x,int st)//处理当前所走的状态  
    {
    	if(x=='d')
    		st|=1;
    	else if(x=='e')
    		st|=2;
    	else if(x=='y')
    		st|=3;
    	return st;
    }
    
    bool check(int x,int y)	 //判断是否能走,可以把师傅或二师兄看做墙不能走 
    {
    	if(map[x][y]=='X' || map[x][y]=='D' || map[x][y]=='E')
    		return false;
    	return true;
    }
    
    char solve(char x,int ok)	//师傅或二师兄所在行和列标记 有多不同 
    {
    	if(ok&&x=='e' || !ok&&x=='d')
    		return 'y';	//'y' 可以记为把师傅和二师兄都被找到的状态 
    	return ok?'d':'e';
    }
    
    //状态压缩 
    void Isit(int x,int y,int ok)//处理师傅或二师兄所在的行和列 
    {
    	for(int i=x-1;i>=0&&check(i,y);i--)
    		map[i][y]=solve(map[i][y],ok);		
    	for(int i=x+1;i<m&&check(i,y);i++)
    		map[i][y]=solve(map[i][y],ok);		
    	for(int j=y-1;j>=0&&check(x,j);j--)
    		map[x][j]=solve(map[x][j],ok);
    	for(int j=y+1;j<n&&check(x,j);j++)
    		map[x][j]=solve(map[x][j],ok);
    } 
    
    void bfs(Node s)
    {
    	queue<Node>q;
    	memset(visit,0,sizeof(visit));
    	s.step=0;
    	s.st=ST_solve(map[s.x][s.y],0);
    	q.push(s);
    	visit[s.x][s.y][s.st]=1;
    	while(!q.empty())
    	{
    		Node a,b;
    		a=q.front();
    		q.pop();
    		if(a.st==3)//问是否能达到3的状态,即师傅和二师兄都被找到
    		{
    			ans=a.step;
    			return;
    		}
    		
    		for(int i=0;i<4;i++)
    		{
    			b.x=a.x+dir[i][0];
    			b.y=a.y+dir[i][1];
    			b.step=a.step+1;
    			b.st=a.st;
    			
    			//if(b.x>=0&&b.x<n&&b.y>=0&&b.y<m&&!visit[b.x][b.y][b.st]&&map[b.x][b.y]=='.')		(错误)
    			if(b.x>=0&&b.x<n&&b.y>=0&&b.y<m&&!visit[b.x][b.y][b.st]&&check(b.x,b.y))
    			{
    				b.st=ST_solve(map[b.x][b.y],b.st);
    				visit[b.x][b.y][b.st]=1;
    				q.push(b);
    			}
    		}
    	}
    }
    
    int main()
    {
    	int tcase=1;
    	while(~scanf("%d%d%d",&n,&m,&t))
    	{
    		Node s; 	
    		for(int i=0;i<n;i++)
    		{
    			scanf("%s",&map[i]);
    			for(int j=0;j<m;j++)
    			{
    				if(map[i][j]=='S')
    				{
    					s.x=i;
    					s.y=j;
    				}
    			}	
    		}
    		
    		for(int i=0;i<n;i++)	//预处理 
    		{
    			for(int j=0;j<m;j++)
    			{
    				if(map[i][j]=='D')
    					Isit(i,j,1);
    				else if(map[i][j]=='E')
    					Isit(i,j,0);
    			}
    		}
    		
    		ans=10005;
    		bfs(s);	
    		printf("Case %d:
    ",tcase++);
    		if(ans<=t)
    			printf("%d
    ",ans);
    		else
    			puts("-1");
    	}
    	return 0;
    }        
    

      

  • 相关阅读:
    Codeforces Round #581 div.2 A,B,C
    19年牛客多校第十场记录
    tarjan 学习笔记
    POJ 3177 Redundant Paths (tarjan无向图求缩点)
    hdu 4738 Caocao's Bridges (tarjan求桥)
    hdu 1540 Tunnel Warfare (线段树维护一维联通区间)
    遍历 redis 数据库
    非web 的 java程序 打成jar包 在linux上运行
    java-疑问-远程连接linux服务器找不到文件路径
    java-查询图片url导出到本地
  • 原文地址:https://www.cnblogs.com/zhangliu/p/7053036.html
Copyright © 2011-2022 走看看