当前位置: 首页 > news >正文

[贪心+搜索] 马走日升级版

题目描述

国际象棋和中国象棋中,马的移动规则相同,都是走“日”字,我们将这种移动方式称为马步移动。如右图所示,从标号为 0 0 0 的点出发,可以经过一步马步移动达到标号为 1 1 1 的点,经过两步马步移动达到标号为 2 2 2 的点。

任给平面上的两点 p p p s s s,它们的坐标分别为 ( x p , y p ) (x_p, y_p) (xp,yp) ( x q , y q ) (x_q, y_q) (xq,yq),其中 x p , y p , x q , y q x_p, y_p, x_q, y_q xp,yp,xq,yq 均为整数。从 ( x p , y p ) (x_p, y_p) (xp,yp) 出发经过一步马步移动可以达到 ( x p + 1 , y p + 2 ) , ( x p + 2 , y p + 1 ) , ( x p + 1 , y p − 2 ) , ( x p + 2 , y p − 1 ) , ( x p − 1 , y p + 2 ) , ( x p − 2 , y p + 1 ) , ( x p − 1 , y p − 2 ) , ( x p − 2 , y p − 1 ) (x_p + 1, y_p + 2), (x_p + 2, y_p + 1), (x_p + 1, y_p - 2), (x_p + 2, y_p - 1), (x_p - 1, y_p + 2), (x_p - 2, y_p + 1), (x_p - 1, y_p - 2), (x_p - 2, y_p - 1) (xp+1,yp+2),(xp+2,yp+1),(xp+1,yp2),(xp+2,yp1),(xp1,yp+2),(xp2,yp+1),(xp1,yp2),(xp2,yp1)。假设棋盘充分大,并且坐标可以为负数。现在请你求出从点 p p p 到点 s s s 至少需要经过多少次马步移动。

输入格式

一行包括 4 4 4 个整数 x p , y p , s p , s q x_p, y_p, s_p, s_q xp,yp,sp,sq

输出格式

含一个整数,表示从点 p p p 到点 s s s 至少需要经过的马步移动次数。

样例

样例输入1:

1 2 7 9

样例输出1:

5

数据范围

对于 40 % 40\% 40% 的数据: x p , y p , x s , y s x_p,y_p,x_s,y_s xp,yp,xs,ys 的绝对值都小于 100 100 100
对于 60 % 60\% 60% 的数据: x p , y p , x s , y s x_p,y_p,x_s,y_s xp,yp,xs,ys 的绝对值都小于 1 0 6 10^6 106
对于 100 % 100\% 100% 的数据: x p , y p , x s , y s x_p,y_p,x_s,y_s xp,yp,xs,ys 的绝对值都小于 1 0 7 10^7 107

题解

对于 40 % 40\% 40% 的数据,可以直接搜索(即普通的马走日)。

#include<bits/stdc++.h>
using namespace std;
int x, y, n, m;
int p, q;
struct node{int u, v, step;//x, y, 步数
};
queue<node> qr;
int dx[8] = {1, -1, 2, -2, 1, -1, 2, -2};
int dy[8] = {2, -2, 1, -1, -2, 2, -1, 1};
map<pair<int, int>, int> fl;
int ans = 0;
int main(){
//	p 是 x 的差,q 是 y 的差p = abs(n - x);q = abs(m - y);qr.push(node{0, 0, 0});while(!qr.empty()){node t = qr.front();
//		printf("%d %d %d\n", t.u, t.v, t.step);if(t.u == p && t.v == q){//搜到了printf("%d", t.step + ans); return 0;}fl[make_pair(t.u, t.v)] = 1;qr.pop();for(int i = 0; i < 8; ++ i){int tx = t.u + dx[i];int ty = t.v + dy[i];if (tx, ty) 没有走过且再范围内qr.push({tx, ty, t.step + 1});}}

对于 100 % 100\% 100% 的数据,考虑将搜索的范围减小。

x x x ∣ x p − s p ∣ |x_p - s_p| xpsp y y y ∣ y p − s p ∣ |y_p - s_p| ypsp。始终让 x ≥ y x \ge y xy
对于 x x x y y y 大于限定值(不要小于 8 8 8)的情况, x x x 先减少 4 4 4(即向该方向移动 2 2 2 步, y y y 可以不变,由于有限定值的限制,所以不用判断)。如果 y y y 走到需要跳的时候(先不动 y y y,需要时再动,移动 2 2 2 步, y y y 可以减少 2 2 2), y y y 减少 2 2 2

接下来搜索就很简单了,建议使用广搜。

代码:

int x, y, n, m;
int p, q;
int ans = 0;
int main(){scanf("%d %d %d %d", &x, &y, &n, &m);p = abs(n - x);q = abs(m - y);while(p + q >= 20){if(p < q){//保持 p >= qswap(p, q);}p -= 4;if(p - 4 <= q * 2){q -= 2;}ans += 2;}bfs();//见上文,范围根据限定值来定,至少限定值加 4输出 ans + bfs 的值
} 

http://www.mrgr.cn/news/48468.html

相关文章:

  • 避免分配大小为零的内存空间
  • 详细介绍AUTOSAR APPL应用层-part6(SWC内部介绍)
  • STL之set、map的使用
  • Spring Boot在医疗B2B平台中的病历数据安全
  • 单片机XMEGA系列芯片dieshot赏析​
  • DAY8 Final等
  • DDR Study - Basic Understanding
  • 一个月学会Java 第12天 剖析static关键字与普通代码块和静态代码块还有final关键字
  • 基于STM32的车牌识别系统
  • 【React】React18核心源码解读
  • 什么电容笔好用?2024双11盘点入手不亏的五大宝藏平替电容笔 !
  • 第十四章 RabbitMQ延迟消息之延迟队列
  • 详细学习 pandas 和 xlrd:从零开始
  • 实测9款AI文件助手!原来最好用的并不是全网称赞的谷歌NotebookLM...
  • 京准:时间频率(北斗授时设备)助力广电网络
  • Unity的Compute Shader如何进行同步?
  • JVS低代码轻应用是什么?是如何拼装的?这篇文章讲的非常详细
  • Docker 教程一(简介)
  • NVM 切换Node.js版本工具
  • 家政行业怎么运营