洛谷1518__两头塔姆沃斯牛

博客探讨了洛谷1518题目的解决方案,重点在于预处理边界避免出界,以及解决移动和判断死循环的问题。作者提到移动时的转向顺序对结果的影响,以及利用专属值来检测循环状态,当牛和农夫走过同一位置时表明进入死循环。文章最后分享了相关代码。
摘要由CSDN通过智能技术生成

0.预处理:在边界设置’*’,这样避免了出界
1.关于移动:形参分别表示x,y,方向,标识符(0表示奶牛,1表示农夫),还有一点就是关于转向:经过事实证明:你只有设顺指针转动的顺序对应0123才可以,对这一点我试验了很多次,也还没想通…欢迎大家思考交流qwq
2.如何判断进入死循环?这个问题让我想了很久,最后本蒟蒻不得已看了眼题解qaq,顿时知道了还有专属值这样一个神奇的东西,大意:当奶牛和农夫在任意两个时刻走过了同一个地方,那么就表示进入循环(不难理解),大家在设置专属值数组时,主要看被乘以的那个数字上限,这决定了你开多大的数组,当然了,一般来说,数组越大越好,不然开小了,偶尔会出现一些难以察觉的bug,很让人头疼

下面是大家最爱的代码时间:

#include<bits/stdc++.h>
using namespace std;

int f[3],c[3];  //分别存储坐标,f[0],f[1],f[2],分别表示x坐标,y坐标
//方向0向北,1向东,2向南,3向西.只有这种顺序才可以满足
int ans=0;        //分钟数 
char map_[12][12];
bool judge[160005];

void move(int x,int y,int towards,int h)  //x表示为行,y表示为列,h==0表示奶牛,h==1表示农夫 
{
	if (towards==0){
		if (map_[x-1][y]=='*')
			if (h==0) c[2]=1;
			else f[2]=1;
		else if (h==0) c[0]--;
		else if (h==1) f[0]--;
	}
	else if (towards==1)
	{
		if (map_[x][y+1]=='*') 
			if (h==0) c[2]=2; 
			else f[2]=2;
		else if (h==0) c[1]++; 
		else if (h==1) f[1]++;
	}
	else if (towards==2)
	{
		if (map_[x+1][y]=='*') 
			if (h==0) c[2]=3; 
			else f[2]=3;
		else if (h==0) c[0]++; 
		else if (h==1) f[0]++;
	}
	else if(towards==3)
	{
		if (map_[x][y-1]=='*') 
			if (h==0) c[2]=0; 
			else f[2]=0;
		else if (h==0) c[1]--; 
		else if (h==1) f[1]--;	//反思:最终的这个c[1]--...f[1]... 
	}				//太容易搞错了 
}


int main()
{
	for(int i=0;i<=11;++i) map_[i][0]='*',map_[i][11]='*'; //设置边界 
	for(int i=0;i<=11;++i) map_[0][i]='*',map_[11][i]='*';
	for(int i=1;i<=10;++i)
	{
		for(int j=1;j<=10;++j)
		{ 
			cin>>map_[i][j]; 
			if(map_[i][j]=='C') c[0]=i,c[1]=j;
			else if(map_[i][j]=='F') f[0]=i,f[1]=j; 
		}
	}
int tdz;  //特征值
	while(c[0]!=f[0]||c[1]!=f[1])
	{
	tdz=f[0]+f[1]*10+c[0]*100+c[1]*1000+f[2]*10000+c[2]*40000; //这个参考了题解,反正系数不要一样,相互呈现递增关系.
		if(judge[tdz] 
		{	//经过了相同的地方,如果是,就是说明进入了死循环 
			cout<<0;
			return 0;
		}
		judge[tdz]=1;  //每走一步就保存
		move(f[0],f[1],f[2],1);    //1判断是农场主,毕竟是农场组先走的(题干说的) 		
		move(c[0],c[1],c[2],0);    //最后的0判断是奶牛 
		++ans;
	}
	cout<<ans;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Shallow_Carl

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

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

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

打赏作者

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

抵扣说明:

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

余额充值