USACO The Tamworth Two

博客介绍了模拟羊和FJ路径的算法思路,通过记录时间三维数组,判断每个格子的时间是否相等。还探讨了如何停止模拟,将初始时间设为1,判断下一个是否为0,同时需分4种情况讨论时间相等问题,且不判断无法到达的点。

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

  一个很直观的想法,分别模拟羊和FJ的路径,记录时间三维数组,i,j,k表示走到第i行第j列方向为k的时间,之后只要分别判断每个格子的时间是否可以相等就OK了,

关键是怎么停下来,先想到的是一共有400种走法,即i(10)*j(10)*k(4),但是在想一下就发现只要把初始时间设为1,判断下一个是否为0即可,然后需分4种情况讨论两个时间是否可以相等,注意不要判断无法到达的点。

/*
ID: jinusac1
PROG: ttwo
LANG: C++
*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int rf[12][12][4]={0},rc[12][12][4],d[4][2]={-1,0,0,1,1,0,0,-1};
char h[12][12];
bool mark[410];
int main()
{
	freopen("ttwo.in","r",stdin);
	freopen("ttwo.out","w",stdout);
	int fi,fj,ci,cj;
	memset(h,'*',sizeof(h));
	for(int i=1;i<=10;i++){
		int j=1;
		char t;
		while((t=getchar())!='\n'){
			h[i][j]=t;
			if(t=='F') {fi=i;fj=j;h[i][j]='.';}
			if(t=='C') {ci=i;cj=j;h[i][j]='.';}
			j++;
		}
	}
	int t=1,dir=0,Tf=0,Tc=0,sf=0,sc=0;
	while(true){
		rf[fi][fj][dir]=t;
		if(h[fi+d[dir][0]][fj+d[dir][1]]=='*') dir=(dir+1)%4;
		else {fi+=d[dir][0];fj+=d[dir][1];}
		if(rf[fi][fj][dir]){
			sf=rf[fi][fj][dir];
			Tf=t-rf[fi][fj][dir]+1;
			break;
		}
		t++;
	}
	t=1;dir=0;
	while(true){
		rc[ci][cj][dir]=t;
		if(h[ci+d[dir][0]][cj+d[dir][1]]=='*') dir=(dir+1)%4;
		else {ci+=d[dir][0];cj+=d[dir][1];}
		if(rc[ci][cj][dir]){
			sc=rc[ci][cj][dir];
			Tc=t-rc[ci][cj][dir]+1;
			break;
		}
		t++;
	}
	int rmin=100000;
	for(int i=1;i<=10;i++)
		for(int j=1;j<=10;j++){
			if(h[i][j]=='*') continue;
			for(int k2=0;k2<4;k2++)
			for(int k1=0;k1<4;k1++){
				int a=rf[i][j][k1],b=rc[i][j][k2];
				if(a==0||b==0) continue;
				if(a<sf&&b<sc){
					if(a==b) rmin=rmin>a?a:rmin;
					else continue;
				}
				else if(a>=sf&&b<sc){
					while(a<=b){
						if(a==b) rmin=rmin>a?a:rmin;
						a+=Tf;
					}
					continue;
				}
				else if(a<sf&&b>=sc){
					while(a>=b){
						if(a==b) rmin=rmin>a?a:rmin;
						b+=Tc;
					}
				}
				else{
					memset(mark,false,sizeof(mark));
					while(a<=400) {mark[a]=true;a+=Tf;}
					while(b<=400){
						if(mark[b]){
							rmin=rmin>b?b:rmin;
							break;
						}
						b+=Tc;
					}
				}
				if(rmin==49) cout<<i<<" "<<j<<endl;
			}
		}
	if(rmin==100000) cout<<0<<endl;
	else cout<<rmin-1<<endl;
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值