P1518 [USACO2.4]两只塔姆沃斯牛 The Tamworth Two

在这里插入图片描述
1.这个题目在洛谷上有一个bug,不能用scanf输入,只能用cin输入,否则会错。我花了3个小时才找到这个错误。。。。个人猜测:(由于window系统写换行的时候,是将回车和换行一起处理,即‘\r\n’被编译器处理成’\n’,虽然回车且换行,但是在缓存区只有一个换行符’\n’且只有输入一个’\n’。而在unix系统要回车换行就要输入两个字符’\r\n’。这样在uninx系统字符输入的时候,只吃掉一个换行是不行的,还要吃一个回车。因此需要两个getchar().)
2.然后,这个题目有一个难点,就是不知道什么情况下人牛才不会相遇,这样我是用一个非常大的数字来判断。比较这个地图非常小,但是没有什么依据。
下面提供一种正确的方法判断是否相遇

设置一个六维数组表示状态,f[fx][fy][cx][cy][ff][cf];表示农民和牛的坐标和转向。如果这个状态没经历过,那么设置为0,否则为1.一旦当遇到状态为1的时候,那么说明这个状态的人,牛之前记录过,那么说明他们永远不会相遇。
#include<stdio.h>
#include<string>
#include<iostream>
using namespace std;
char map[12][12];
typedef struct 
{
	int x;
	int y;
	int turn;
}subject;

int main()
{
	subject famer, cow;
	//memset(map, '*', sizeof(map));
	for (int i = 0; i <= 11; i++)
	{
		map[0][i] = '*';
		map[i][0] = '*';
		map[11][i] = '*';
		map[i][11] = '*';
	}
		
	for (int i = 1; i <= 10; i++)
	{
		for (int j = 1; j <= 10; j++)
		{
			cin >> map[j][i];  
			//如果用scanf("%c",&map[j][i]); 后面要两个getchar()
			if (map[j][i] == 'F')
			{
				famer.turn = 0;
				famer.x = j;
				famer.y = i;
			}
			
			else
				if (map[j][i] == 'C')
			{
				cow.turn = 0;
				cow.x = j;
				cow.y = i;
			}
		}
		//如果用scanf输入,这里别忘了。
		//getchar();
		//getchar();
	}
	int time = 0;
	//int num = 1;
	while ((famer.x != cow.x) || (famer.y != cow.y))
	{
		if (time > 200000)
		{
			printf("0");
			return 0;
		}
		time++;
		int judge_f = 1;
		int judge_c = 1;
		if (famer.turn == 0&& judge_f)  //人往上走
		{
			if (map[famer.x][famer.y-1] == '*')//转弯
				famer.turn = (famer.turn + 1) % 4;
			else   //向上走
				famer.y -= 1;
			judge_f = 0;
		}
		if (famer.turn == 1 && judge_f)    //人往右走
		{
			if (map[famer.x+1][famer.y] == '*')//转弯
				famer.turn = (famer.turn + 1) % 4;
			else   //向右走
				famer.x += 1;
			judge_f = 0;
		}
		if (famer.turn == 2 && judge_f)    //人往下走
		{
			if (map[famer.x][famer.y+1] == '*')//转弯
				famer.turn = (famer.turn + 1) % 4;
			else   //向下
				famer.y += 1;
			judge_f = 0;
		}
		if (famer.turn == 3 && judge_f)    //人往左走
		{
			if (map[famer.x-1][famer.y] == '*')//转弯
				famer.turn = (famer.turn + 1) % 4;
			else   //向左走
				famer.x -= 1;
			judge_f = 0;
		}
		if (cow.turn == 0 && judge_c)  //牛往上走
		{
			if (map[cow.x][cow.y - 1] == '*')//转弯
				cow.turn = (cow.turn + 1) % 4;
			else   //向上走
				cow.y -= 1;
			judge_c = 0;
		}
		if (cow.turn == 1 && judge_c)    //牛往右走
		{
			if (map[cow.x+ 1][cow.y ] == '*')//转弯
				cow.turn = (cow.turn + 1) % 4;
			else   //向右走
				cow.x += 1;
			judge_c = 0;
		}
		if (cow.turn == 2 && judge_c)    //牛往下走
		{
			if (map[cow.x][cow.y + 1] == '*')//转弯
				cow.turn = (cow.turn + 1) % 4;
			else   //向下走
				cow.y += 1;
			judge_c = 0;
		}
		if (cow.turn == 3 && judge_c)    //牛往左走
		{
			if (map[cow.x- 1][cow.y ] == '*')//转弯
				cow.turn = (cow.turn + 1) % 4;
			else   //向左走
				cow.x -= 1;
			judge_c = 0;
		}
		//printf("第%d次:(%d,%d),(%d,%d)\n", num++, famer.x, famer.y, cow.x, cow.y);
	}
	printf("%d",time);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值