usaco The Tamworth Two 两只塔姆沃斯牛

在一个10x10的网格中,两只牛和一个农夫进行追逐游戏。此文章详细介绍了如何使用C++通过模拟牛和农夫的行为来解决这个问题,并分享了解决方案中的技巧及遇到的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

两只牛在森林里故意走丢了.农民 John 开始用他的专家技术追捕这两头牛.你的任务是模拟他们的
行为(牛和 John). 追击在 10x10 的平面网格内进行.一个格子可以是: 一个障碍物, 两头牛(它们
总在一起), 或者农民 John.
两头牛和农民 John 可以在同一个格子内(当他们相遇时),但是他们都不能进入有障碍的格子.
一个格子可以是:
. 空地 * 障碍物 C 两头牛 F 农民 John
这里有一个地图的例子::
*...*.....
......*...
...*...*..
..........
...*.F....
*.....*...
...*......
..C......*
...*.*....
.*.*......
*...*.....
......*...
...*...*..
..........
...*.F....
*.....*...
...*......
..C......*
...*.*....
.*.*......
牛在地图里以固定的方式游荡.每分钟,它们可以向前移动或是转弯.如果前方无障碍且不会离开地
图,它们会按照原来的方向前进一步.否则它们会用这一分钟顺时针转 90 度.
农民 John, 深知牛的移动方法,他也这么移动.
每次(每分钟)农民 John 和两头牛的移动是同时的.如果他们在移动的时候穿过对方,但是没有在同
一格相遇,我们不认为他们相遇了.当他们在某分钟末在某格子相遇,那么追捕结束.开始时,John
和牛都面向北方.
PROGRAM NAME: ttwo
INPUT FORMAT
Lines 1-10:
每行 10 个字符,表示如上文描述的地图.
SAMPLE INPUT (file ttwo.in)
*...*.....
......*...
...*...*..
..........
...*.F....
*.....*...
...*......
..C......*
...*.*....
.*.*......
OUTPUT FORMAT
输出一个数字,表示 John 需要多少时间才能抓住牛们.输出 0,如果 John 无法抓住牛.
32
SAMPLE OUTPUT (file ttwo.out)

49



一开始我想的是bfs,一般求最短时间啥的不都是用bfs的吗,但是这题我发现不通,数据很小可以大模拟,搞事情反正我有不怕大新闻。v1数组记录的是人到达那点的方向v2是牛的,如果它两又同时到达某两点,而且和之前的方向一样那就循环了,return 0即可。可是第一次提交的时候提醒我编译错误。

可是在编译器里面正常运行啊,然后我就想到之前有次用map当数组时和头文件里面的map函数冲突,然后我改了头文件果然通过了。看来<bits/stdc++.h>用起来方便可还是要注意啊。代码可以再变短一点因为F和C的前进规则一样可以用函数代替不用像我这样把人和牛的步骤都写出来。

/*
ID: jinbo wu
TASK: ttwo
LANG:C++
*/
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int d[4][2]={-1,0,0,1,1,0,0,-1};
int  v1[15][15];
int v2[15][15];
char a[15][15];
int x1,x2,y1,y2;
struct pos
{
	int x,y,dir;
};
queue<pos> q1,q2;
int bfs()
{
	memset(v1,-1,sizeof(v1));
	memset(v2,-1,sizeof(v2));
    pos p1,p2;
    int dx,dy;
    p1.x=x1,p1.y=y1,p1.dir=0;
    q1.push(p1);
    p2.x=x2,p2.y=y2,p2.dir=0;
    q2.push(p2);
    int t=0;
	while(1)
	{
		p1=q1.front();
		q1.pop();
		p2=q2.front();
		q2.pop();
	    if(p1.x==p2.x&&p1.y==p2.y)
	    return t;
	    if(v1[p1.x][p1.y]==p1.dir&&v2[p2.x][p2.y]==p2.dir)
	    return 0;
	    v1[p1.x][p1.y]=p1.dir,v2[p2.x][p2.y]=p2.dir;
	    dx=p1.x+d[p1.dir][0];
	    dy=p1.y+d[p1.dir][1];
	    if(a[dx][dy]=='*'||dx<1||dx>10||dy<1||dy>10)
	    {
	      p1.dir=(p1.dir+1)%4;
	      q1.push(p1);
	    }
	    else 
	    {
	    	p1.x=dx,p1.y=dy;
	    	q1.push(p1);
		}
		dx=p2.x+d[p2.dir][0];
		dy=p2.y+d[p2.dir][1];
		if(a[dx][dy]=='*'||dx<1||dx>10||dy<1||dy>10)
		{
			p2.dir=(p2.dir+1)%4;
		    q2.push(p2);
		}
		else
		{
			p2.x=dx,p2.y=dy;
			q2.push(p2);
		}
		t++;
	}
	
	
}
int main()
{
	freopen("ttwo.in","r",stdin);
	freopen("ttwo.out","w",stdout);
	for(int i=1;i<=10;i++)
	for(int j=1;j<=10;j++)
	{
	cin>>a[i][j];
	if(a[i][j]=='F')
	{
		x1=i,y1=j;
	}
	if(a[i][j]=='C')
	{
		x2=i,y2=j;
	}
    }
	int ans=bfs();
	cout<<ans<<endl;
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值