洛谷题单指南-模拟和高精度-P1518 [USACO2.4] 两只塔姆沃斯牛 The Tamworth Two

原题链接:https://www.luogu.com.cn/problem/solution/P1518

题意解读:

此题是一道模拟题,关键要解决几个问题:1、如何转换方向 2、如何在地图中移动 3、如何判断无法抓住牛。

解题思路:

定义char a[10][10]用于存储地图,cx,cy和fx,fy分别代表牛、Farmer所在的位置,cdir、fdir分别代表牛、Farmer运动的方向。

1、如何转换方向

cdir、fdir初始值为0,表示向上移动,1表示向右移动(顺时针旋转90度),2表示向下移动(再顺时针旋转90度),3表示

向左移动(再顺时针旋转90度)。

以牛转换方向为例:当牛无法往前移动时,转换方向的操作为cidr = (cdir + 1) % 4

2、如何在地图中移动

在地图中移动,本质上就是左标的变化,根据当前的方向,决定行、列的变化,可以设定一个坐标变化的表格:

  向上   向右   向下   向左
行坐标变化值 -1 0 1 0
列坐标变化值 0 1 0 -1

代码中,定义两个数组即可:

int dx[4] = {-1, 0, 1, 0}; //不同运动方向的x坐标变化
int dy[4] = {0, 1, 0, -1}; //不同运动方向的y坐标变化

以牛移动为例:当前牛的位置cx,cy,移动方向cdir,将要移动到的位置是cx + dx[cdir],cy + dy[cdir]

3、如何判断无法抓住牛

如果能抓取牛,很容易判断,当牛、Farmer移动位置之后,cx == fx && cy == fy则表示抓住了,那如何判断无法抓住牛呢?有两种方法:

方法一:复杂版。

记录每一次牛、Farmer的状态,也就是6个关键变量的值:cx、cy、fx、fy、cdir、fdir,如果这6个变量的值重复出现,则表示路径陷入的某种循环,

永远不会相遇。可以借助哈希思想,计算100000 * cx + 10000 * cy + 1000 * fx + 100 * fy + cdir * 10 + fdir的值,判断该值是否重复出现过即可。

方法二:简单版。

地图是10 * 10,每次有4个方向可走,牛每次有400种走法,Farmer每次也有400种走法,如果在400 * 400 = 160000次之后还没有相遇,基本可以认为

陷入了某种循环,抓不到了,把次数放大一点到200000,超过200000次还无法相遇,则判定抓不到。

下面实现采用此方法。

100分代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 10;

char a[N][N];

int dx[4] = {-1, 0, 1, 0}; //不同运动方向的x坐标变化
int dy[4] = {0, 1, 0, -1}; //不同运动方向的y坐标变化

int main()
{
    int cx, cy, fx, fy;
    int cdir = 0; //牛运动方向,0:上  1:右  2:下  3:左
    int fdir = 0; //Farmer运动方向
    for(int i = 0; i < N; i++)
    {
        for(int j = 0; j < N; j++)
        {
            cin >> a[i][j];
            if(a[i][j] == 'C') cx = i, cy = j; //记录牛初始位置
            if(a[i][j] == 'F') fx = i, fy = j; //记录Farmer初始位置
        }
    }

    int cnt = 0;
    while(cnt < 200000)
    {
        cnt++;

        //牛能否往前
        if(cx + dx[cdir] >= 0 && cx + dx[cdir] < N && cy + dy[cdir] >= 0 && cy + dy[cdir] < N && a[cx + dx[cdir]][cy + dy[cdir]] != '*')
        {
            a[cx + dx[cdir]][cy + dy[cdir]] = 'C';//牛往前一步
            a[cx][cy] = '.'; //原位置先设为空地
            cx = cx + dx[cdir], cy = cy + dy[cdir]; //更新牛的位置
        }
        else cdir = (cdir + 1) % 4;// 牛不能往前,则变换方向
            
        //Farmer能否往前
        if(fx + dx[fdir] >= 0 && fx + dx[fdir] < N && fy + dy[fdir] >= 0 && fy + dy[fdir] < N && a[fx + dx[fdir]][fy + dy[fdir]] != '*')
        {
            a[fx + dx[fdir]][fy + dy[fdir]] = 'F';//Farmer往前一步
            if(a[fx][fy] != 'C') a[fx][fy] = '.'; //原位置如果没有被牛占据,则设为空地
            fx = fx + dx[fdir], fy = fy + dy[fdir];//更新Farmer的位置
        }
        else fdir = (fdir + 1) % 4;// Farmer不能往前,则变换方向

        if(cx == fx && cy == fy) 
        {
            cout << cnt;
            break;
        }
    }
    if(cnt >= 200000) cout << 0;

    return 0;
}

 

posted @ 2024-01-19 11:55  五月江城  阅读(67)  评论(0编辑  收藏  举报