【NOIP practice】BSOJ 1097 拯救博士 扫描法

1097 -- 【模拟试题】拯救博士
Description
  话说在到BASHU国集中的途中, Mike博士神秘失踪了,最后发现是被外星人绑架了,幸好外星人目前还是在地球上活动,并且知道外星人不了解地球,所以使用的交通工具是最土的汽车。而且Mike博士身上装有用于发射移动路线的装置。 
那个装置太旧了,以至于只能发射有关的移动路线的方向信息。 
  寻找Mike博士的任务便交给了你,编写程序,通过使用一张地图帮助研究所找到Mike博士。程序必须能表示出该车最终所有可能的位置。 
  地图是矩形的,上面的符号用来标明哪儿可以行车哪儿不行。"."表示那块地方是可以行进的,而符号"X"表示此处不通。而用"*"表示发现Mike博士失踪的地点. 
  车能向四个方向移动:向北(向上),向南(向下),向西(向左),向东(向右)。
Input
  第一行包含两个用空格隔开的自然数R和C,1≤K≤200,1≤C≤200,分别表示地图中的行数和列数。 
  以下的K行中每行都包含一组符号("."或"X"或"*")用来描述地图上相应的部位。 
  接下来的一行包含一个自然数N,1≤N≤1000,表示一组方向的长度。 
  接下来的N行幅行包含下述单词中的任一个:NORTH(北)、SOUTH(南)、WEST(西)和EAST(东),表示汽车移动的方向,任何两个连续的方向都不相同。
Output
  输出文件应包含用K行表示的地图(象输入文件中一样),字符"*"应该仅用来表示Mike博士最终可能出现的位置。
Sample Input
3 3
...
..X
*..
3
EAST
NORTH
WEST
Sample Output
*..
*.X

...


怎么说呢..这道题一开始没看懂BFS写了好久,以为只是规定了方向,其实还有一个时间限制,某一步只能走一个方向。

其实知道“某一步只能走给定方向”时,这道题就比较明显了,就是纯粹的模拟。

方法:每次输入方向,都把给定方向的matrix值设置为步数,遇到‘X’就停止,每次都只能在matrix值为当前步数-1的位置开始横向或纵向更新,以保证时间上的有序。最后,遇到值为总步数的点就输出‘.’即可!


#include<iostream>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;
int n,m,k;
int mat[505][505]={0};
//嫌麻烦后面都用的cin  cout输出.. 
int main(){
    scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	  for(int j=1;j<=m;j++)
	  {
	  	char ch;
	  	cin>>ch;
	  	if(ch=='X')mat[i][j]=-2;
	  	if(ch=='.')mat[i][j]=-1;//一定要把为'.'的mat[][] 设为-1,因为要从mat[][]为0的点开始走
		  //这样处理,有且仅有为'*'的点值为0,即起点。 
	   }     
	   
	   
	scanf("%d",&k);
    string s;
	for(int p=1;p<=k;p++)
	  {
	  cin>>s;
	  	for(int i=1;i<=n;i++)
	  	  	for(int j=1;j<=m;j++)
	  	  	{
	  	  		if(mat[i][j]==p-1)//满足时间的有序,从上一步开始走。 
	  	  		{
				//每个点横向或纵向更新mat[][]为当前步数p,遇到X就停止 
	  	  		if(s=="EAST")
	  	  		{
	  	  			for(int q=j+1;q<=m;q++){if(mat[i][q]==-2)break;mat[i][q]=p;}
				}
				else if(s=="SOUTH")
				{
					for(int q=i+1;q<=n;q++){if(mat[q][j]==-2)break;mat[q][j]=p;}
				}
				else if(s=="WEST")
				{
					for(int q=j-1;q>=1;q--){if(mat[i][q]==-2)break;mat[i][q]=p;}
				}
				else if(s=="NORTH")
				{
					for(int q=i-1;q>=1;q--){if(mat[q][j]==-2)break;mat[q][j]=p;}
				}
				
			    }
			}
	  }
	  
	  for(int i=1;i<=n;i++)
	    {
	    	for(int j=1;j<=m;j++)
	    	{
	    		if(mat[i][j]==-2)cout<<"X";
	    		else if(mat[i][j]==k)cout<<"*";//这个点是最终走到的点之一,即可能点。 
	    		else cout<<".";
			}
			cout<<endl;
		}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值