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

题目描述

两只牛逃跑到了森林里。Farmer John 开始用他的专家技术追捕这两头牛。你的任务是模拟他们的行为(牛和 John)。

追击在 10×10 的平面网格内进行。一个格子可以是:一个障碍物,两头牛(它们总在一起),或者 Farmer John。两头牛和 Farmer John 可以在同一个格子内(当他们相遇时),但是他们都不能进入有障碍的格子。

一个格子可以是:

  • . 空地;
  • * 障碍物;
  • C 两头牛;
  • F Farmer John。

这里有一个地图的例子:

*...*.....
......*...
...*...*..
..........
...*.F....
*.....*...
...*......
..C......*
...*.*....
.*.*......

牛在地图里以固定的方式游荡。每分钟,它们可以向前移动或是转弯。如果前方无障碍(地图边沿也是障碍),它们会按照原来的方向前进一步。否则它们会用这一分钟顺时针转 90 度。 同时,它们不会离开地图。

Farmer John 深知牛的移动方法,他也这么移动。

每次(每分钟)Farmer John 和两头牛的移动是同时的。如果他们在移动的时候穿过对方,但是没有在同一格相遇,我们不认为他们相遇了。当他们在某分钟末在某格子相遇,那么追捕结束。

读入十行表示地图。每行都只包含 10 个字符,表示的含义和上面所说的相同。保证地图中只有一个 F 和一个 CF 和 C 一开始不会处于同一个格子中。

计算 Farmer John 需要多少分钟来抓住他的牛,假设牛和 Farmer John 一开始的行动方向都是正北(即上)。 如果 John 和牛永远不会相遇,输出 0。

输入格式

输入共十行,每行 10 个字符,表示如上文描述的地图。

输出格式

输出一个数字,表示 John 需要多少时间才能抓住牛们。如果 John 无法抓住牛,则输出 0。

输入输出样例

输入 

*...*.....
......*...
...*...*..
..........
...*.F....
*.....*...
...*......
..C......*
...*.*....
.*.*......

输出 

49

代码

无注释版

#include<bits/stdc++.h>
using namespace std;
int main(){
	int a[12][12]={};//*=1  .=0
	char s[11];
	for(int i=1;i<11;i++){
	    a[0][i]=a[i][0]=a[i][11]=a[11][i]=1;
	}
	int cr,cc,cd=0,fr,fc,fd=0,step=0;
	for(int i=0;i<10;i++){
		cin>>s;
		for(int j=0;j<10;j++){
			if(s[j]=='*'){
				a[i+1][j+1]=1;
			}
		    else if(s[j]=='F'){
				fr=i+1;fc=j+1;
			}
			else if(s[j]=='C'){
				cr=i+1;cc=j+1;
			}
        }
	}
	while(step<16000000){
		if(fd==0){
			if(a[fr-1][fc]==0) fr--;
			else fd++;
		}
		else if(fd==1){
			if(a[fr][fc+1]==0) fc++;
			else fd++;
		}
		else if(fd==2){
			if(a[fr+1][fc]==0) fr++;
			else fd++;
		}
		else if(fd==3){
			if(a[fr][fc-1]==0) fc--;
			else fd=0;
		}
		if(cd==0){
			if(a[cr-1][cc]==0) cr--;
			else cd++;
		}
		else if(cd==1){
			if(a[cr][cc+1]==0) cc++;
			else cd++;
		}
		else if(cd==2){
			if(a[cr+1][cc]==0) cr++;
			else cd++;
		}
		else if(cd==3){
			if(a[cr][cc-1]==0) cc--;
			else cd=0;
		}
		step++;
		if(fr==cr && fc==cc){
			cout<<step;
			return 0;
		}
	}
	cout<<0;
}

有注释版

#include<bits/stdc++.h>      // 引入所有标准库,包括iostream、algorithm等
using namespace std;

int main() {
    int a[12][12] = {};    // 创建一个12x12的数组,用来存储地图,额外的1行1列用于边界处理
    char s[11];            // 用于存储输入的一行地图数据
    
    // 将地图的边界设为障碍物,方便处理
    for(int i = 1; i < 11; i++) {   
        a[0][i] = a[i][0] = a[i][11] = a[11][i] = 1;  // 给地图四周加上障碍物
    }
    
    // 变量初始化
    int cr, cc, cd = 0;    // cr, cc 是牛的行列位置,cd 是牛的移动方向(0: 上,1: 右,2: 下,3: 左)
    int fr, fc, fd = 0;    // fr, fc 是 Farmer John 的行列位置,fd 是 Farmer John 的移动方向
    int step = 0;          // 步数(分钟)

    // 读入地图数据
    for(int i = 0; i < 10; i++) {
        cin >> s;             // 读取一行地图
        for(int j = 0; j < 10; j++) {
            if(s[j] == '*') {    // 如果是障碍物
                a[i + 1][j + 1] = 1;  // 标记为障碍物(1)
            }
            else if(s[j] == 'F') {   // 如果是 Farmer John 的位置
                fr = i + 1;  // Farmer John 的行坐标
                fc = j + 1;  // Farmer John 的列坐标
            }
            else if(s[j] == 'C') {   // 如果是牛的位置
                cr = i + 1;  // 牛的行坐标
                cc = j + 1;  // 牛的列坐标
            }
        }
    }

     // 牛的行坐标
                cc = j + 1;  // 牛的列坐标
            }
        }
    }

    // 开始模拟移动过程
    while(step < 16000000) {   // 最大步数设置为 16000000,防止无限循环(合理的上限)
        
        // Farmer John 的移动(遵循顺时针方向:上 -> 右 -> 下 -> 左)
        if(fd == 0) {   // 0: 上
            if(a[fr - 1][fc] == 0) {  // 如果上方没有障碍
                fr--;  // 向上移动
            } else {
                fd++;  // 向右转
            }
        } else if(fd == 1) {   // 1: 右
            if(a[fr][fc + 1] == 0) {  // 如果右方没有障碍
                fc++;  // 向右移动
            } else {
                fd++;  // 向下转
            }
        } else if(fd == 2) {   // 2: 下
            if(a[fr + 1][fc] == 0) {  // 如果下方没有障碍
                fr++;  // 向下移动
            } else {
                fd++;  // 向左转
            }
        } else if(fd == 3) {   // 3: 左
            if(a[fr][fc - 1] == 0) {  // 如果左方没有障碍
                fc--;  // 向左移动
            } else {
                fd = 0;  // 向上转
            }
        }

        // 牛的移动(同样遵循顺时针方向)
        if(cd == 0) {   // 0: 上
            if(a[cr - 1][cc] == 0) {  // 如果上方没有障碍
                cr--;  // 向上移动
            } else {
                cd++;  // 向右转
            }
        } else if(cd == 1) {   // 1: 右
            if(a[cr][cc + 1] == 0) {  // 如果右方没有障碍
                cc++;  // 向右移动
            } else {
                cd++;  // 向下转
            }
        } else if(cd == 2) {   // 2: 下
            if(a[cr + 1][cc] == 0) {  // 如果下方没有障碍
                cr++;  // 向下移动
            } else {
                cd++;  // 向左转
            }
        } else if(cd == 3) {   // 3: 左
            if(a[cr][cc - 1] == 0) {  // 如果左方没有障碍
                cc--;  // 向左移动
            } else {
                cd = 0;  // 向上转
            }
        }

        step++;  // 增加步数

        // 判断 Farmer John 和牛是否相遇
        if(fr == cr && fc == cc) {  
            cout << step;  // 如果相遇,输出步数并结束
            return 0;
        }
    }
    
    // 如果在 16000000 步内没有相遇,输出 0
    cout << 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值