两只塔姆沃斯牛 The Tamworth Two

两只牛逃跑到了森林里。Farmer John 开始用他的专家技术追捕这两头牛。你的任务是模拟他们的行为(牛和 John)。

追击在 10 \times 1010×10 的平面网格内进行。一个格子可以是:一个障碍物,两头牛(它们总在一起),或者 Farmer John。两头牛和 Farmer John 可以在同一个格子内(当他们相遇时),但是他们都不能进入有障碍的格子。

一个格子可以是:

. 空地;

  • 障碍物;
    C 两头牛;
    F Farmer John。
    这里有一个地图的例子:





.F…


…C…

.
..
牛在地图里以固定的方式游荡。每分钟,它们可以向前移动或是转弯。如果前方无障碍(地图边沿也是障碍),它们会按照原来的方向前进一步。否则它们会用这一分钟顺时针转 90 度。 同时,它们不会离开地图。

Farmer John 深知牛的移动方法,他也这么移动。

每次(每分钟)Farmer John 和两头牛的移动是同时的。如果他们在移动的时候穿过对方,但是没有在同一格相遇,我们不认为他们相遇了。当他们在某分钟末在某格子相遇,那么追捕结束。

读入十行表示地图。每行都只包含 10 个字符,表示的含义和上面所说的相同。保证地图中只有一个 F 和一个 C。F 和 C 一开始不会处于同一个格子中。

计算 Farmer John 需要多少分钟来抓住他的牛,假设牛和 Farmer John 一开始的行动方向都是正北(即上)。 如果 John 和牛永远不会相遇,输出 0。
思路都在下面,我和其他题解有一个不一样的地方是,我判断不可能抓到的条件是cnt已经过了10000分钟,这个不会超时,并且如果10X10的格子抓一万次才抓到这个数据也够恶心的了

#include<bits/stdc++.h>
using namespace std;
char m[15][15];
int main(){
	int dx,dy,nx,ny;
	for(int i=1;i<=10;i++){ //将整个布局记录进去,并且把F和C的坐标记录下来
		for(int j=1;j<=10;j++){
			cin>>m[i][j];
			if(m[i][j]=='F'){
			dx=i;dy=j; //
			}else if(m[i][j]=='C'){ 
			nx=i;ny=j; //
			}
		}
	}
    //cout<<dx<<" "<<dy<<" "<<nx<<" "<<ny<<endl; //检查用的 看看坐标有没有错误
    int cnt=0,idx[4]={-1,0,1,0},idy[4]={0,1,0,-1},d=0,n=0;
    bool sht=true; 
    int flag=0,flag1=0; //为F和C各立一个flag,如果他们转了4次以上方向就证明是个死胡同,直接输出0即可
    while(sht){
    	if(flag==4||cnt>10000){  //如果flag改变了五次,或者cnt走了一万次就证明是死胡同,直接输出0即可 
    		cout<<0;
    		return 0;
		}
    	if(dx==nx&&dy==ny){ //如果F和C的坐标相等,直接输出cnt记录的数量即可
    		cout<<cnt;
    		return 0;
		}
    	if(m[dx+idx[d]][dy+idy[d]]=='.'){ //核心代码
    		m[dx][dy]='.';    //每次先判断一下当前方向的下一个坐标是不是. 如果是的话
			dx+=idx[d];       //将当前坐标赋值为. 然后将坐标移到下一个位置
			dy+=idy[d];
			flag=0; //如果能走得通,就把flag重置
		    }else //如果走不动 就d++改变一下方向并且flag要++;
			{
			d++;
			d=d%4;
			flag++;}
		if(m[nx+idx[n]][ny+idy[n]]=='.'){ //C的思路也是一样,改一下坐标即可
    		m[nx][ny]='.';
			nx+=idx[n];
			ny+=idy[n];
			flag1=0;
		    }else
			{
			n++;
			n=n%4;
			flag1++;}
		cnt++; //不管是移动了还是试图换了方向,都要加1分钟
//		cout<<dx<<" "<<dy<<" "<<nx<<" "<<ny<<" "<<d<<endl; 调试用,方便看看他们每次的坐标
	}
	cout<<cnt;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

这咋又bug了嘛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值