P1518 两只塔姆沃斯牛 The Tamworth Two

该博客详细讨论了P1518题目——两只塔姆沃斯牛在遇到障碍物时如何转向的问题。通过两种思路分析,解释了如何判断牛是否会在某一时刻相遇,以及如何排除形成环的情况。文章重点在于理解牛的行走路径和如何避免无限循环。

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

https://www.luogu.org/problemnew/show/P1518

思路一:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll ,ll > P;
#define INF 0xf3f3f3f
const int Max=10000+10;
int dx[4]= {-1,0,1,0};
int dy[4]= {0,1,0,-1};
int c[11][11][4],f[11][11][4];
char m[11][11];
bool ok(int x,int y) {
	return x>0&&x<=10&&y>0&&y<=10;
}
int gcd(int x,int y) {
	return y?gcd(y,x%y):x;
}
void exgcd(int a,int b,int &x,int &y) {
	if(!b) {
		x=1;
		y=0;
		return;
	}
	exgcd(b,a%b,y,x);
	y-=a/b*x;
	return;
}
int main() {
	int fx,fy,cx,cy;
	memset(c,-1,sizeof c);
	memset(f,-1,sizeof f);
	for(int i=1; i<=10; i++)
		for(int j=1; j<=10; j++) {
			cin>>m[i][j];
			if(m[i][j]=='C') {
				cx=i;
				cy=j;
			}
			if(m[i][j]=='F') {
				fx=i;
				fy=j;
			}
		}
		
	int t=0;
	f[fx][fy][0]=0,c[cx][cy][0]=0;
	int tx,ty,nowc=0,nowf=0;
	while(1) {
		tx=fx+dx[nowf];
		ty=fy+dy[nowf];
		if(ok(tx,ty)) {
			if(m[tx][ty]=='*')
				nowf=(nowf+1)%4;
			else
				fx=tx,fy=ty;
		} else
			nowf=(nowf+1)%4;
		if(f[fx][fy][nowf]==-1)
			f[fx][fy][nowf]=++t;
		else
			break;
	}
	int ftime=t+1;
	t=0;
	while(1) {
		tx=cx+dx[nowc];
		ty=cy+dy[nowc];
		if(ok(tx,ty)) {
			if(m[tx][ty]=='*')
				nowc=(nowc+1)%4;
			else
				cx=tx,cy=ty;
		} else
			nowc=(nowc+1)%4;
		if(c[cx][cy][nowc]==-1)
			c[cx][cy][nowc]=++t;
		else
			break;
	}
	int ctime=t+1;
	int ans=INF;
	      
	for(int i=1; i<=10; i++)
		for(int j=1; j<=10; j++)
			for(int k=0; k<4; k++)
				for(int l=0; l<4; l++) {
					if(f[i][j][k]!=-1&&c[i][j][l]!=-1)
					{
							if(f[i][j][k]<=f[fx][fy][nowf]&&c[cx][cy][nowc]>=c[i][j][l]) {
						if(f[i][j][k]==c[i][j][l])
								ans=min(ans,f[i][j][k]);
						continue;
					}
					if(f[i][j][k]<=f[fx][fy][nowf]) {
						if(f[i][j][k]>=c[i][j][l]) {
							if((f[i][j][k]-c[i][j][l])%(ctime-c[cx][cy][nowc])==0)
								ans=min(ans,f[i][j][k]);
						}
						continue;
					}
					if(c[i][j][l]<=c[cx][cy][nowc]) {
						if(c[i][j][l]>=f[i][j][k]) {
							if((c[i][j][l]-f[i][j][k])%(ftime-f[fx][fy][nowf])==0)
								ans=min(ans,c[i][j][l]);
						}
						continue;
					}
					int xtim=ctime-c[cx][cy][nowc],ytim=ftime-f[fx][fy][nowf];
					int ch,gd=gcd(xtim,ytim);
					if(f[i][j][k]>c[i][j][l]) {
						if((f[i][j][k]-c[i][j][l])%gd!=0)
							continue;
						ch=(f[i][j][k]-c[i][j][l])/gd;
					} else {
						if((c[i][j][l]-f[i][j][k])%gd!=0)
							continue;
						ch=(c[i][j][l]-f[i][j][k])/gd;
					}
					int x,y;
					exgcd(xtim,ytim,x,y);
					ans=min(ans,x*ch*xtim+f[i][j][k]);
					}
					   
				
				}
	
	if(ans==INF)
		printf("0\n");
	else
		printf("%d\n",ans);
	return 0;
}
/*
...*.....*
**.......*
.....*..*.
*.*.......
.........*
F.....*.*.
**.*C....*
.......**.
.....*....
....*.*...
146
*/

思路二:

牛跟人一起走,遇到障碍物就转向,同时标记一下每个状态,若形成环则不会相遇,否则输出相遇是的时间

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll ,ll > P;
#define INF 0xf3f3f3f
const int Max=10000+10;
int dx[4]= {-1,0,1,0};
int dy[4]= {0,1,0,-1};
bool m[21][21],vis[21][21][4][21][21][4];
int fx,fy,cx,cy,ft,ct;
void dfs(int step) {
	if(fx==cx&&fy==cy) {
		printf("%d\n",step);
		return ;
	}
	if(vis[fx][fy][ft][cx][cy][ct]) {
		printf("0\n");
		return ;
	}
	vis[fx][fy][ft][cx][cy][ct]=1;
	
	int tx=fx+dx[ft],ty=fy+dy[ft];
	if(!m[tx][ty])
		fx=tx,fy=ty;
	else
		ft=(ft+1)%4;
	tx=cx+dx[ct],ty=cy+dy[ct];
	if(!m[tx][ty])
		cx=tx,cy=ty;
	else
		ct=(ct+1)%4;
	dfs(step+1);

}
int main() {
	memset(m,0,sizeof m);//0 可以走 1有障碍
	memset(vis,0,sizeof vis);//1 标记
	char c;
	for(int i=0;i<=11;i++)
	    m[0][i]=1,m[11][i]=1,m[i][0]=1,m[i][11]=1;
	for(int i=1; i<=10; i++)
		for(int j=1; j<=10; j++) {
			cin>>c;
			if(c=='C')
				cx=i,cy=j;
			if(c=='F')
				fx=i,fy=j;
			if(c=='*')
				m[i][j]=1;
		}
	ft=0,ct=0;
	dfs(0);

	return 0;
}

 

回答: 题目P1518 \[USACO2.4\] 两只塔姆沃斯是一道模拟题,题目要求判断Farmer John和两头是否会相遇。解题思路可以分为两种方法。一种方法是记录二者的状态,如果出现了与前面相同的状态则说明陷入了死循环。具体实现步骤可以使用数组来记录Farmer John和两头的坐标、方向等状态信息,然后判断是否出现了重复的状态。另一种方法是利用博弈的思想,如果二者会同时回到一种状态,那么说明他们不会再相遇了,因为这时候他们已经陷入了一种对称性的状态。通过判断是否存在一种线性关系,可以确定二者是否会相遇。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* [P1518 [USACO2.4]两只塔姆沃斯 The Tamworth Two](https://blog.youkuaiyun.com/TD123456q/article/details/125688037)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [洛谷P1518 [USACO2.4]两只塔姆沃斯 The Tamworth Two 题解 (C/C++)](https://blog.youkuaiyun.com/Jason__Jie/article/details/115027619)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [(移动方向状态标志)P1518 [USACO2.4]两只塔姆沃斯 The Tamworth Two题解](https://blog.youkuaiyun.com/m0_57221330/article/details/119980758)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值