原题链接: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;
}
标签:fy,P1518,fx,洛谷题,塔姆沃,cy,cx,fdir,cdir From: https://www.cnblogs.com/jcwy/p/17974338