USACO 2.4 ttwo(The Tamworth Two)

本文介绍了一个简单的模拟游戏问题,即农夫追捕两头牛的过程。游戏在一个10x10的网格上进行,需要通过编程模拟农夫与牛的行为,并判断两者是否会相遇。文章提供了完整的解题思路和C++代码实现。

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

题目描述

两只牛逃跑到了森林里。农夫约翰开始用他的经验追捕这两头牛。你的任务是模拟他们的行为。
追捕在10x10的平面网格内进行。一个格子可以是空的或者包含:

  • 一个障碍物
  • 两只牛(它们总在一个格子),或者
  • 农夫约翰

牛和农夫约翰可以在同一个格子内(当他们“相遇”时),但他们都不能进入有障碍的格子。
每个格子可以如下:

  • . 空地
  • * 障碍物
  • C 牛
  • F 农夫

牛在地图里以固定的方式游荡。每分钟,它们可以向前移动或是转弯。通常,它们会按照原来的方向前进一步。如果前方有障碍或者“向前走”会使它们离开网格,那么它们会用这一分钟顺时针旋转90度。
农夫约翰深知牛的移动方法,也这么移动。
每分钟农夫约翰和牛同时移动。如果他们在移动的时候擦肩而过,就不算他们相遇了。当他们某分钟末在同一格子,追捕就结束了。
读入十行表示牛,农夫约翰和障碍物初始位置的网格。每行都只包含10个字符,含义和上面所说相同。保证只有一个农夫和一对牛。牛和农夫约翰一开始不会处于同一个格子中。
计算牛和农夫约翰相遇的时间。假设牛和农夫一开始的行动方向都是“北方”。如果他们永远不会相遇,输出0。

(此部分借鉴了https://blog.youkuaiyun.com/qq397470071/article/details/6923314

程序名:ttwo

输入格式

一至十行:十行,每行十个字符

输入样例(文件 ttwo.in)

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

输出格式

一个整数,农夫约翰与牛相遇时的分钟数。如果他们永远不会见面,请输出0。

输出样例(文件 ttwo.out)

49

解题思路

对于这么水的题,我只能呵呵。10*10的网格,如此小的数据量,而且只有一条路,模拟法绰绰有余。测试农夫与牛是否不会相遇有两种方法:一、设置几个数组,存放农夫与牛的位置与方向,测试是否重复,如果重复就是死循环,退出;二、农夫与牛有10*10=100种位置,有4种方向,总共有4*100=400种状态,两者共有400*400=160000种状态,而每一分钟,它们的位置都会发生变化,因此如果160000分钟以后两者还没有相遇,那么就是永远不会相遇了。我是按照第一种方法来的,有点笨,大家可以用第二种方法。

代码

/*
PROB:ttwo
LANG:C++
*/
#include <fstream>
using namespace std;
int fx,fy,cx,cy; //人、牛所在位置 
int fw,cw; //人、牛所走方向 
int bcx[100000],bcy[100000],bcw[100000],bfx[100000],bfy[100000],bfw[100000]; //牛、人以前位置、方向 
int i,j;
char k[10][10];
ifstream in("ttwo.in");
ofstream out("ttwo.out");

void work(int n)
{
    if(fx==cx&&fy==cy)
    {
        out<<n<<endl;
        in.close();
        out.close();
        return;
    } //结束
    for(i=0;i<n;i++)
        if(fx==bfx[i]&&fy==bfy[i]&&fw==bfw[i]&&cx==bcx[i]&&cy==bcy[i]&&cw==bcw[i])
        {
            out<<0<<endl;
            in.close();
            out.close();
            return;
        } //测试是否重复 
    bfx[n]=fx;
    bfy[n]=fy;
    bfw[n]=fw;
    bcx[n]=cx;
    bcy[n]=cy;
    bcw[n]=cw; //储存此步 
    switch(fw)
    {
        case 1:fx--;break; //北
        case 2:fy++;break; //东
        case 3:fx++;break; //南
        case 4:fy--;break; //西
    }
    switch(cw)
    {
        case 1:cx--;break;
        case 2:cy++;break;
        case 3:cx++;break;
        case 4:cy--;break;
    } //行动
    if(fx<0||fx>9||fy<0||fy>9||k[fx][fy]=='*')
    {
        fx=bfx[n];
        fy=bfy[n];
        fw++;
    }
    if(fw>4)
        fw=1;
    if(cx<0||cx>9||cy<0||cy>9||k[cx][cy]=='*')
    {
        cx=bcx[n];
        cy=bcy[n];
        cw++;
    }
    if(cw>4)
        cw=1; //转向
    work(n+1);
}

int main()
{
    for(i=0;i<10;i++)
        for(j=0;j<10;j++)
        {
            in>>k[i][j];
            if(k[i][j]=='F')
            {
                fx=i;
                fy=j;
            }
            else if(k[i][j]=='C')
            {
                cx=i;
                cy=j;
            }
        }
    fw=1;
    cw=1;
    work(0);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值