算法沉淀第二天(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;
}

结语:

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

相关推荐
Yupureki3 小时前
从零开始的C++学习生活 8:list的入门使用
c语言·c++·学习·visual studio
SunkingYang3 小时前
详细介绍C++中通过OLE操作excel时,一般会出现哪些异常,这些异常的原因是什么,如何来解决这些异常
c++·excel·解决方案·闪退·ole·异常类型·异常原因
jc06203 小时前
4.4-中间件之gRPC
c++·中间件·rpc
十五年专注C++开发4 小时前
C++类型转换通用接口设计实现
开发语言·c++·跨平台·类设计
im_AMBER4 小时前
杂记 15
java·开发语言·算法
胡萝卜3.04 小时前
掌握string类:从基础到实战
c++·学习·string·string的使用
爱coding的橙子4 小时前
每日算法刷题Day70:10.13:leetcode 二叉树10道题,用时2h
算法·leetcode·深度优先
江公望4 小时前
通过QQmlExtensionPlugin进行Qt QML插件开发
c++·qt·qml
Syntech_Wuz4 小时前
从 C 到 C++:容器适配器 std::stack 与 std::queue 详解
数据结构·c++·容器··队列