信息学奥赛一本通1330:【例8.3】最少步数

题目

【题目描述】

在各种棋中,棋子的走法总是一定的,如中国象棋中马走“日”。有一位小学生就想如果马能有两种走法将增加其趣味性,因此,他规定马既能按“日”走,也能如象一样走“田”字。他的同桌平时喜欢下围棋,知道这件事后觉得很有趣,就想试一试,在一个(100×100)的围棋盘上任选两点A、B,A点放上黑子,B点放上白子,代表两匹马。棋子可以按“日”字走,也可以按“田”字走,俩人一个走黑马,一个走白马。谁用最少的步数走到左上角坐标为(1,1)的点时,谁获胜。现在他请你帮忙,给你A、B两点的坐标,想知道两个位置到(1,1)点可能的最少步数。

【输入】

A、B两点的坐标。

【输出】

最少步数。

【输入样例】

12 16
18 10

【输出样例】

8
9

代码

#include<iostream>
#include<queue>
using namespace std;
const int N = 112;
bool chess[N][N];  // 记录棋盘情况
// 十二个方向
int dx[12] = { -2,-1,-2,-2,-1,-2,2,1,2,2,1,2 };
int dy[12] = { -1,-2,-2,1,2,2,-1,-2,-2,1,2,2 };
int ans1, ans2;
struct node {
	int x, y, step;
	node(int x, int y, int step) :x(x), y(y), step(step) {}
};
queue<node> q;
void push(int x, int y, int step) {   // 点(x,y)入队
	q.emplace(x, y, step);
	chess[x][y] = true;
}
bool check(int x, int y) {   // 判断(x,y)是否能走
	return x >= 1 && x <= 100 && y >= 1 && y <= 100 && !chess[x][y];
}
void bfs(int x1, int y1, int x2, int y2) {  //计算(1,1)分别到(x1,y1)和(x2,y2)的最短距离
	bool flag1 = false, flag2 = false;
	push(1, 1, 0);
	while (q.size()) {
		node t = q.front();
		q.pop();
		for (int i = 0; i < 12; i++) {
			int nx = t.x + dx[i], ny = t.y + dy[i];
			if (check(nx, ny)) {
				push(nx, ny, t.step + 1);
				if (nx == x1 && ny == y1 && !flag1) flag1 = true, ans1 = t.step + 1;
				if (nx == x2 && ny == y2 && !flag2) flag2 = true, ans2 = t.step + 1;
			}
		}
		if (flag1 && flag2) return;
	}
}
int main() {
	int x1, y1, x2, y2;
	cin >> x1 >> y1 >> x2 >> y2;
	bfs(x1, y1, x2, y2);
	cout << ans1 << endl << ans2 << endl;

	return 0;
}

评测结果

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值