hiho_99_骑士问题

题目大意

给定国际象棋8x8棋盘上三个起始点,三个骑士分别从三个起始点开始移动(骑士只能走日字,且骑士从任意一点出发可以走遍整个棋盘)。现要求三个骑士汇聚到棋盘上某个点,且使得骑士到达该点所移动的次数总和最小。求该最小移动次数。 
题目连接:骑士问题

题目分析

典型的搜索,最短路径可以使用BFS。骑士数只有三个,因此可以求出每个骑士到达棋盘上所有点的移动的次数,再遍历一遍棋盘,求出最小次数和。

实现

#pragma once
#pragma execution_character_set("utf-8")
// 本文件为utf-8 编码格式
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<unordered_map>
#include<unordered_set>
#include<string>
#include<stack>
#include<queue>
using namespace std;
struct Node{
	int x, y, step;
	Node(int xx, int yy, int s) :x(xx), y(yy), step(s){};
};
int move_step[9][9][3];
bool visited[9][9];
int move_inc[8][2] = { { -2, -1 }, { -2, 1 }, { -1, 2 }, { 1, 2 }, { 2, 1 }, { 2, -1 }, { 1, -2 }, { -1, -2 } };
void Bfs(int start_x, int start_y, int knight){
	memset(visited, false, sizeof(visited));
	queue<Node> Q;
	Node node(start_x, start_y, 0);
	Q.push(node);
	visited[start_x][start_y] = true;
	while (!Q.empty()){
		node = Q.front();
		Q.pop();
		move_step[node.x][node.y][knight] = node.step;
		for (int i = 0; i < 8; i++){
			int next_x = node.x + move_inc[i][0];
			int next_y = node.y + move_inc[i][1];
			if (next_x >= 1 && next_x <= 8 &&
				next_y >= 1 && next_y <= 8 &&
				!visited[next_x][next_y]){
				visited[next_x][next_y] = true;
				Q.push(Node(next_x, next_y, node.step + 1));
			}
		}
	}
}
void Init(){
	memset(move_step, -1, sizeof(move_step));
}
int MinStep(){
	int min = 1 << 30;
	for (int r = 1; r <= 8; r++){
		for (int c = 1; c <= 8; c++){
			min = min < (move_step[r][c][0] + move_step[r][c][1] + move_step[r][c][2]) ?
			min : (move_step[r][c][0] + move_step[r][c][1] + move_step[r][c][2]);
		}
	}
	return min;
}
int main(){
	int T;
	char row, col;
	scanf("%d", &T);
	int start_x[3];
	int start_y[3];

	while (T--){
		for (int i = 0; i < 3; i++){
			getchar();
			scanf("%c%c", &row, &col);
			start_x[i] = row - ‘A‘ + 1;
			start_y[i] = col - ‘0‘;
		}
		for (int i = 0; i < 3; i++){
			Bfs(start_x[i], start_y[i], i);
		}
		int result = MinStep();
		printf("%d\n", result);
	}
	return 0;
}
时间: 2024-12-18 18:41:50

hiho_99_骑士问题的相关文章

[COGS746] [网络流24题] 骑士共存

★★☆   输入文件:knight.in   输出文件:knight.out   简单对比 时间限制:1 s   内存限制:128 MB 骑士共存问题 «问题描述: 在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘 上某些方格设置了障碍,骑士不得进入. «编程任务: 对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑 士,使得它们彼此互不攻击. «数据输入: 由文件knight.in给出输入数据.第一行有2 个正整数n 和m (1<=n<

【Codevs1922】骑士共存问题(最小割,二分图最大匹配)

题意: 在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入. 对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑士,使得它们彼此互不攻击. n<=200,m<=n^2 思路:经典的二分图最大匹配问题,采用黑白点染色的思想. 如果按照相邻点黑白不同染色,可以发现每次跳到的点必定与现在所在点不同色,二分图最大匹配即可. 这里用最小割来解决,因为不能允许任何黑白点之间的任何一条边有流量,符合最小割的思想. 1

【树形DP】BZOJ1040-[ZJOI2008]骑士

[题目大意] 有n个骑士,给出他们的能力值和最痛恨的一位骑士.选出一个骑士军团,使得军团内没有矛盾的两人(不存在一个骑士与他最痛恨的人一同被选入骑士军团的情况),并且,使得这支骑士军团最具有战斗力,求战斗力的最大值. [思路] 首先yy一下,可以知道这是一个基环森林.我们可以用以下方法: 首先在每一棵基环树的环上任意找到一条边(用dfs来实现),记它的两个端点为u和v.然后删掉这条边(我这里用的方法是记录u,v在对方容器中的位置,并在后续操作中忽略这条边).由于u和v不能同时取,在删掉u和v之间

bzoj1040 骑士

Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里,在和平环境中安逸了数百年的Z国又怎能抵挡的住Y国的军队.于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一个真龙天子的降生,带领正义打败邪恶.骑士团是肯定具有打败邪恶势力的能力的,但是骑士们互相之间往往有一些矛盾.每个骑士都有且仅有一个自己最厌恶的骑士(当然不是他自己),他是绝对不

骑士飞行棋第三版(上色)

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace 骑士飞行棋 8 { 9 class Program 10 { 11 12 //在下面的数组存储我们游戏地图各个关卡 13 //数组的小标为0的元素对应地图上的第一格 下标为1的元素对应第二格...下标为n的元素对应n+1

BZOJ 1040: [ZJOI2008]骑士( 树形dp )

这是一个森林中, 每棵树上都有一个环...每棵树单独处理, 找出环上任意一条边断开, 限制一下这条边两端点的情况, 然后就可以树dp了.. ------------------------------------------------------------------------ #include<cstdio> #include<algorithm> #include<cstring> #include<cctype> using namespace

Ni骑士(ni)

搞了半天八数码弄不出来就只好来打题解  这道题是在搜索a碰到的(链接: http://pan.baidu.com/s/1jG9rQsQ ) 感觉题目最大亮点就是这英文简写"ni", 真是令人感慨出题老师的才华啊  好了,废话不多说  题目内容如下(闲烦请无视之,下下方有简单的介绍): [问题描述] 贝 西(Bessie)在卡摩洛遇到了棘手的情况:她必须穿越由Ni骑士把守的森林. 骑士答应Bessie只要 Bessie 能给他们带来一丛灌木就能安全穿越森林.时间宝贵,Bessie 必须尽

骑士走棋盘

问题陈述: 骑士游历(Knight tour)在十八世纪初备受数学家与拼图迷的注意,究竟它是什么时候被提出已不可考.骑士的走法为国际象棋的走法,类似中国象棋的马,骑士可以由任意一个位置出发,他如何走完所有的位置? 问题解法: 骑士的走法,基本上可以用递归的方法来解决,但是纯粹的递归在维度大时相当没有效率.一个聪明的解法由J.C.Warnsdorff在1823年提出,简单的说,先将最难的位置走完,接下来的路就是宽广,骑士所要走的下一步:为下一步再做选择时,所能走的步数最少的一步.使用这个方法,在不

湖人主帅懊恼曾被骑士解雇 这里边几个意思?

http://www.xy280.com/bbs/news/201502102000.htmlhttp://www.xy280.com/bbs/news/201502102001.htmlhttp://www.xy280.com/bbs/news/201502102002.htmlhttp://www.xy280.com/bbs/news/201502102003.htmlhttp://www.xy280.com/bbs/news/201502102004.htmlhttp://www.xy28