I'm stuck! ccf模拟题。

9 篇文章 0 订阅

ccf模拟题。

 

I’m stuck!

时间限制:1.0s
内存限制:256.0MB

 

问题描述

给定一个R行C列的地图,地图的每一个方格可能是'#', '+', '-', '|', '.', 'S', 'T'七个字符中的一个,分别表示如下意思:

 

'#': 任何时候玩家都不能移动到此方格;

'+': 当玩家到达这一方格后,下一步可以向上下左右四个方向相邻的任意一个非'#'方格移动一格;

'-': 当玩家到达这一方格后,下一步可以向左右两个方向相邻的一个非'#'方格移动一格;

'|': 当玩家到达这一方格后,下一步可以向上下两个方向相邻的一个非'#'方格移动一格;

'.': 当玩家到达这一方格后,下一步只能向下移动一格。如果下面相邻的方格为'#',则玩家不能再移动;

'S': 玩家的初始位置,地图中只会有一个初始位置。玩家到达这一方格后,下一步可以向上下左右四个方向相邻的任意一个非'#'方格移动一格;

'T': 玩家的目标位置,地图中只会有一个目标位置。玩家到达这一方格后,可以选择完成任务,也可以选择不完成任务继续移动。如果继续移动下一步可以向上下左右四个方向相邻的任意一个非'#'方格移动一格。

此外,玩家不能移动出地图。

请找出满足下面两个性质的方格个数:

1. 玩家可以从初始位置移动到此方格;

2. 玩家可以从此方格移动到目标位置。

输入格式

输入的第一行包括两个整数R 和C,分别表示地图的行和列数。(1 ≤ R, C ≤ 50)。

接下来的R行每行都包含C个字符。它们表示地图的格子。地图上恰好有一个'S'和一个'T'。

输出格式

如果玩家在初始位置就已经不能到达终点了,就输出“I'm stuck!”(不含双引号)。否则的话,输出满足性质的方格的个数。

样例输入

5 5

--+-+

..|#.

..|##

S-+-T

####.

样例输出

2

样例说明

如果把满足性质的方格在地图上用'X'标记出来的话,地图如下所示:

--+-+

..|#X

..|##

S-+-T

#include<bits/stdc++.h>
int xx[5]={1,-1,0,0};
int yy[5]={0,0,1,-1};
int vis[51][51];
int can[51][51];
char a[51][51];
int r,c;
int flag;
int counter;
void  bfs(int x,int y)
{
  int dx,dy,rear,front;
  rear=front=0;
 
  
    while(front<=rear)
   {     
    if(a[x][y]=='+'||a[x][y]=='S'||a[x][y]=='T')
    {
	  
      for(int i=0;i<4;i++)
       {
       
    	dx=x+xx[i];
        dy=y+yy[i];
        if(dx>=0&&dx<r&&dy>=0&&dy<c&&a[dx][dy]!='#'&&vis[dx][dy]!=1)
        {
       	    vis[dx][dy]=1;
       	    if(flag==0&&a[dx][dy]=='T')
       	    counter++;
       	    if(flag)
       	    can[dx][dy]=1;
        	bfs(dx,dy);
        	rear++;
        	
		}
	  }
	 
		
   }
   else if(a[x][y]=='-')
   {
   	
      for(int i=2;i<4;i++)
      {
    	dx=x+xx[i];
        dy=y+yy[i];
        if(dx>=0&&dx<r&&dy>=0&&dy<c&&a[dx][dy]!='#'&&vis[dx][dy]!=1)
        {  if(flag)
            can[dx][dy]=1;
             if(flag==0&&a[dx][dy]=='T')
       	     counter++;
       	    vis[dx][dy]=1;
        	bfs(dx,dy);
        	rear++;
        	
		}
      }
      
    }
    else if(a[x][y]=='|')
    {
    	
      for(int i=0;i<2;i++)
     {
    	dx=x+xx[i];
        dy=y+yy[i];
        if(dx>=0&&dx<r&&dy>=0&&dy<c&&a[dx][dy]!='#'&&vis[dx][dy]!=1)
        {  vis[dx][dy]=1;
		    if(flag)
       	    can[dx][dy]=1;
       	      if(flag==0&&a[dx][dy]=='T')
       	    counter++;
        	bfs(dx,dy);
        	rear++;
        
		}
	 }

   }
	
	else if(a[x][y]=='.')
	{
		
    
    	dx=x+xx[0];
        dy=y+yy[0];
        if(dx>=0&&dx<r&&dy>=0&&dy<c&&a[dx][dy]!='#'&&vis[dx][dy]!=1)
        {    if(flag)
            can[dx][dy]=1;
            if(flag==0&&a[dx][dy]=='T')
       	    counter++;
       	    vis[dx][dy]=1;
        	bfs(dx,dy);
         	rear++;	
		}	
	}
    front++;
 }
return;
}
int main()
{
    int x_e,x_s,k1=51,k2=51;
	scanf("%d %d",&r,&c);
	memset(vis,0,sizeof(vis));
	memset(can,0,sizeof(can));
	for(int i=0;i<r;i++)
	{
		scanf("%s",&a[i]);
	}
	flag=1;
	for(int i=0;i<r;i++)
	 {
	   for(int j=0;j<c;j++)
		{	
	     if(a[i][j]=='S')
	     {
		   vis[i][j]=1;
		   bfs(i,j);
		}
	   }
     }
	   flag=0;
	   int ans=0;

bfs(0,2);
for(int i=0;i<r;i++)
{
	for(int j=0;j<c;j++)
	{
		if(can[i][j]==1&&a[i][j]!='T'&&a[i][j]!='S')
    	{   memset(vis,0,sizeof(vis));
			ans++;
	    	bfs(i,j);
	    }
	    if(a[i][j]=='T')
	    {
	    	k1=i;
	    	k2=j;
		}
	}
}
    if(can[k1][k2]==1)
	printf("%d",ans-counter);
	else
	printf("I'm stuck!");
}

 

 

####X

一开始少了一个vis[dx][dy]=1;30分后来改过来了90分然后才发现我没判断I’m stuck!的条件所幸很简单我又加上了。我觉得我的代码比网上大多数都好理解吧。虽然有点长。

 

说一下思路吧,一开始时判断能从S到达的点,并把这些点做标记。就是can数组。后来在从被标记的点出发,看他能不能到T点,能的话counter加一。最后再用标记的点个数的总数减去那些能到T的点。i'm stuck的条件也很好判断,当我再给那些点做标记的时候如果T点没标记的话证明从s出发不能到T;

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值