小 X 与机器人 (betago)

题目描述

小 X 最近对战胜韩国围棋大神李世石的 A l p h a G o AlphaGo AlphaGo 很感兴趣,所以小 X X X 自己写了一个叫 做 B e t a G o BetaGo BetaGo的人工智能程序(简称 A I AI AI) , 这个 B e t a G o BetaGo BetaGo 会做什么呢?
小 X 首先想要让 B e t a G o BetaGo BetaGo 做到自己在棋盘上落子, 这一点 A l p h a G o AlphaGo AlphaGo 是由程序员来完成的。小 X X X 的设想是这样的: 在棋盘的边框上放置一个小机器人, 这个小机器人会沿着棋盘的边框移动到最接近落子点的位置,然后伸出它的机械臂将棋子放到棋盘上。 这里面最关键的一步是如何让小机器人在棋盘的边框上沿着最短的路径移动,小 X X X 想请你帮他编个程序解决这个问题。
众所周知,围棋棋盘大小为 19 × 19 19 × 19 19×19(如下图所示) , 图中加粗的一圈即为边框。
在这里插入图片描述
我们用一对整数 (x, y) 来表示棋盘上第 x 条横线(从下往上数)与第 y 条竖线(从左往右数)的交叉点,如上图中边框上的 A 点用( 6, 1) 表示, B 点用 (10, 19) 表示,小机器人初始时放置在 (x1,y1) 这个位置上, 它想要移动到 (x2, y2) 这个位置上。 (x1, y1) 和(x2, y2) 一定是棋盘边框上的交叉点每一步小机器人可以从当前位置移动到相邻(上下左右)的某个位置上, 即每次可以从 (x, y) 移动到 (x - 1, y) 、 (x + 1, y) 、 (x, y - 1) 、 (x, y + 1) 四个位置中的一个, 但是它不能走出或走进棋盘,也就是说它只能沿着棋盘的边框移动到相邻位置, 这就意味着任一时刻相邻位置都恰好只有两个。
BetaGo 会告诉小机器人最少需要走多少步, 但小 X 还是很担心 B e t a G o BetaGo BetaGo 有的时候会失控,从而告诉他一个错误值。
为此小 X 只好求助你, 希望你编一个程序计算从 ( x 1 , y 1 ) (x1, y1) (x1,y1) 沿着棋盘的边框移动到 ( x 2 , y 2 ) (x2, y2) (x2,y2) 最少需 要 走 多 少步 。 上 图 中 从 A A A ( 6 , 1 ) ( 6 , 1 ) (61 移 动 到 B 点 ( 10 , 19 ) (10 , 19) (1019) 最 少需 要 走 32 32 32 步 , 移 动 路线 是 : ( 6 , 1 ) → ( 5 , 1 ) → ( 4 , 1 ) → ( 3 , 1 ) → ( 2 , 1 ) → ( 1 , 1 ) → ( 1 , 2 ) → ( 1 , 3 ) → … … → ( 1 , 19 ) → ( 2 , 19 ) → … … → ( 10 , 19 ) ( 6 , 1 ) → ( 5 , 1 ) → ( 4 , 1 ) → ( 3 , 1 ) → ( 2 , 1 ) → ( 1 , 1 ) → (1 , 2 ) → (1 , 3 ) →……→(1, 19) →(2, 19) →……→(10, 19) 615141312111(12(13(119(219(1019

题目分析

方法一:

三种情况:
( 1 ) (1) 1如果对面两个点
( 2 ) (2) 2如果相邻直线上的两个点 [ a b s ( x 1 − x 2 ) + a b s ( y 1 − y 2 ) abs(x1-x2)+abs(y1-y2) abs(x1x2)+abs(y1y2)]
( 3 ) (3) 3如果在同一条线上[判断 a b s ( x 1 − x 2 ) abs(x1-x2) abs(x1x2) a b s ( y 1 − y 2 ) abs(y1-y2) abs(y1y2)]

Code

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

const ll MAXN = 1010, mod = 998244353;

inline int read() {
	int x = 0;
	char c = getchar();
	while (c < '0' || c > '9') c = getchar();
	while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return x;
}

ll a1, a2, b1, b2, tmx, tmy;
signed main() {
	cin >> a1 >> a2 >> b1 >> b2;
	if (abs(a1 - b1) == 18) {
		tmx = 18 + a2 - 1 + b2 - 1;
		tmy = 18 + 19 - a2 + 19 - b2;
	}
	if (abs(a2 - b2) == 18) {
		tmx = 18 + a1 - 1 + b1 - 1;
		tmy = 18 + 19 - a1 + 19 - b1;
	}
	if (a1 == b1)tmx = abs(a2 - b2);
	if (a2 == b2)tmx = abs(a1 - b1);
	if (tmx + tmy == 0)tmx = abs(a1 - b1) + abs(a2 - b2);
	if ((tmx > tmy) && (tmy != 0)) {
		cout << tmy;
	} else cout << tmx;
	return 0;
}
方法二:

爆搜出奇迹!

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

const ll MAXN = 110, mod = 998244353, dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};;

inline int read() {
	int x = 0;
	char c = getchar();
	while (c < '0' || c > '9') c = getchar();
	while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return x;
}

int a, b, c, d, f[MAXN][MAXN], vis[MAXN][MAXN];

int bfs() {
	queue<pair<int, int>> q;
	q.push({a, b}), vis[a][b] = 0;
	while (q.size()) {
		auto t = q.front();
		q.pop();
		for (int i = 0; i < 4; i++) {
			int X = t.first + dx[i], Y = t.second + dy[i];
			if (!f[X][Y]) continue;
			if (vis[X][Y] > vis[t.first][t.second] + 1)vis[X][Y] = vis[t.first][t.second] + 1, q.push({X, Y});
			if (X == c && Y == d)return vis[X][Y];
		}
	}
}
int main() {
	for (int i = 1; i <= 19; i++)f[i][1] = f[i][19] = f[1][i] = f[19][i] = 1;
	memset(vis, 0x3f, sizeof vis);
	a = read(), b = read(), c = read(), d = read();
	cout << bfs();
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值