算法沉淀第二天(Catching the Krug)

目录

引言:

[Catching the Krug](#Catching the Krug)

题意分析

逻辑梳理

代码实现

结语:


引言:

今天是算法沉淀的第二天,开的是CF评级为1300的一道题,这道题用分类讨论就可以解决了,甚至不需要用到算法,那么接下来,话不多说,我们就进入今天的算法讲解--------------------->

​​​​​​​


Catching the Krug

按照惯例,我们先来看题目

题意分析

题目链接如下Problem - 2152B - Codeforces

不想跳转的可看下图

这道题虽然题目描述的很长,其实目的很简单,就是有俩个人,假设分别是A人和B人,然后,A人负责逃跑,B人负责追击,如果B人追不到A人就输出-1,如果B人如果能追到A人就输出最少的追击次数,A和B在同一个格子上就算追击到了

A不想被B追到,所以A会用最优的方式来躲B,然后B想快点追上A,所以B也会用最优的方式来追击A

然后会问你t种情况,每种情况先告诉你A的坐标再告诉你B的坐标

那A和B的走法是怎么走的呢,A每次可以横着或者竖着走一格(也可以不走),B则是每次可以走的位置是他所在的格子的周围一圈(也可以不走),然后,走法是A先走,再B走,这样轮流走

那么,题目意思讲完了,接下来,就进入逻辑梳理环节咯


逻辑梳理

首先,A只能横着或竖着走,但B可以斜着走,所以如果B想要快点追到A,肯定会堵A的路,A最终肯定会被抓到,所以输出-1的情况是不存在的

那么,既然A已经知道自己会被堵,那么A肯定会移动到最远的位置,然后不动,这样才能躲得更久,那么A可以去上下的边界,也可以去左右的边界,那么具体去哪里也要看A与B的位置关系

那具体怎么移,我们可以通过B来看,不管A怎么移动,因为B的可移动性远高于A,所以可以相当于是B的平推,因为B可以通过斜着走堵住A的未来路,所以这时候就只会有俩种情况了,一种是B沿着水平方向平推到边界,另一种是B沿着竖直方向平推到边界

那么,我们只需要去这俩种情况的最大值就好了,因为A想晚点被抓到,所以B肯定要走更多的操作次数

那么,情况分析完了,接下来,就进行分类讨论就好啦

我们可以通过A,B的x轴坐标的差异,分为三种情况,接着再细分,假设A的坐标为(x1,y1),B的坐标为(x2,y2)

若x1<x2

这时候,A的位置在B的左侧,我们可以对A的位置通过y的差距来进行进一步细分

如果y1>y2

这说明A的位置在B的左上角,A可以往左走,也可以往上走,那B追到A的移动次数就是B到左边界和上边界的俩个值中的较大值

如果y1>y2

这说明A的位置在B的左下角,A可以往左走,也可以往下走,那B追到A的移动次数就是B到左边界和下边界的俩个值中的较大值

如果y1==y2

这说明A的位置在B的正左边,这时候B只要一直往左走就能抓到了,如果A想上下走,B只要斜着往左压过去就可以了,所以这种情况下的移动次数就是B到左边界的移动次数

若x1>x2

这个就跟上面那个同理了,只是算的时候数据会变化

若x1==x2

这个情况就比较特殊了,这个就跟上面x1!=x2时,但y1==y2一样,只需要算出B到对应边界的操作次数就好了

那么所有情况就讨论完了,接下来就进入代码实现的环节啦


代码实现

代码的思路逻辑梳理已经讲的很清楚啦,那么接下来,就直接展示AC码啦

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;

int t;

void solve()
{
	long long n, x1, y1, x2, y2;
	cin >> n >> x1 >> y1 >> x2 >> y2;
	if (x1 < x2)
	{
		if (y1 == y2)
		{
			cout << x2 << endl;
		}
		else if (y1 < y2)
		{
			cout << max(x2, y2) << endl;
		}
		else
		{
			cout << max(x2, n - y2) << endl;
		}
	}
	else if (x1 > x2)
	{
		if (y1 == y2)
		{
			cout << n - x2 << endl;
		}
		else if (y1 < y2)
		{
			cout << max(n - x2, y2) << endl;
		}
		else
		{
			cout << max(n - x2, n - y2) << endl;
		}
	}
	else
	{
		if (y1 < y2)
			cout << y2 << endl;
		else
			cout << n - y2 << endl;
	}
}

int main()
{
	cin >> t;
	while (t--)
	{
		solve();
	}
	return 0;
}

结语:

今日算法讲解到此结束啦,希望对你们有所帮助,谢谢观看,如果觉得不错可以分享给朋友哟。有什么看不懂的可以评论问哦,

相关推荐
nianniannnn几秒前
力扣104.二叉树的最大深度 110. 平衡二叉树
算法·leetcode·深度优先
_深海凉_10 分钟前
LeetCode热题100-只出现一次的数字
算法·leetcode·职场和发展
yashuk16 分钟前
C语言 vs. C++ ,哪个更适合初学者?
c语言·c++·面向对象编程·初学者·学习路径
-许平安-23 分钟前
MCP项目笔记十(客户端 MCPClient)
c++·笔记·ai·raii·mcp·pluginapi·plugin system
一只旭宝26 分钟前
【C++ 入门精讲2】函数重载、默认参数、函数指针、volatile | 手写笔记(附完整代码)
c++·笔记
nianniannnn29 分钟前
力扣206.反转链表 92.反转链表II
算法·leetcode·链表
澈20736 分钟前
哈希表实战:从原理到手写实现
算法·哈希算法
旖-旎44 分钟前
哈希表(存在重复元素||)(4)
数据结构·c++·算法·leetcode·哈希算法·散列表
Run_Teenage1 小时前
Linux:认识信号,理解信号的产生和处理
linux·运维·算法
John.Lewis1 小时前
C++进阶(8)智能指针
开发语言·c++·笔记