Sicily 1936. Knight Moves 解题报告

1936_Knight_Moves

题目链接:

http://soj.me/1936

题目大意: 给出一个8×8的棋盘,骑士走的是“日”字型,给出骑士的初始位置和目标位置,问最少经过多少步可以到达目标位置。

思路: 比较简单的宽度优先搜索题目,只要从起始位置开始,每一步搜索完这一层能够达到的所有点,这样你能保证第一次找到目标点的话就一定是最少的步数到达的。

代码:

#include <iostream>
#include <queue>
using namespace std;

int move_x[8] = { -1, -2, -2, -1, 1, 2, 2, 1 };
int move_y[8] = { -2, -1, 1, 2, 2, 1, -1, -2 };

bool visited[8][8];

class Point {
public:
	int x;
	int y;
	Point(int xx = 0, int yy = 0) {
		x = xx;
		y = yy;
	}
};

Point target;

int bfs(const Point &start);
bool checkPoint(const int x, const int y);

int main() {
	int numTestcases;
	cin >> numTestcases;
	while (numTestcases--) {
		string a, b;
		cin >> a >> b;
		Point start = Point(a[1] - ‘1‘, a[0] - ‘a‘);
		target.x = b[1] - ‘1‘;
		target.y = b[0] - ‘a‘;
		for (int i = 0; i < 8; ++i) {//每次重置整个棋盘未被访问
			for (int j = 0; j < 8; ++j) {
				visited[i][j] = false;
			}
		}
		cout << "To get from " << a << " to " << b << " takes " << bfs(start)
				<< " knight moves." << endl;
	}

	return 0;
}

int bfs(const Point &start) {
	visited[start.x][start.y] = true;
	if (start.x == target.x && start.y == target.y)
		return 0;
	else {
		int numMoves = 1;
		queue<Point> cur, next;//next装下一层可以到达的点
		cur.push(start);
		while (!cur.empty()) {//下一层还有点可以访问到
			while (!cur.empty()) {//将当层所有点能到达的点放到下一层
				for (int i = 0; i < 8; ++i) {
					Point p = Point(cur.front().x + move_x[i],
							cur.front().y + move_y[i]);
					if (p.x == target.x && p.y == target.y) {
						return numMoves;
					} else if (checkPoint(p.x, p.y)) {
						next.push(p);
						visited[p.x][p.y] = true;
					}
				}
				cur.pop();
			}
			while (!next.empty()) {//将下一层的点设置为当层的点,准备下一轮操作
				cur.push(next.front());
				next.pop();
			}
			numMoves++;
		}
		return numMoves;
	}
}

bool checkPoint(const int x, const int y) {//判断一个点是否可以访问
	if (x >= 0 && x < 8 && y >= 0 && y < 8 && !visited[x][y])
		return true;
	else
		return false;
}
时间: 2024-11-29 10:24:27

Sicily 1936. Knight Moves 解题报告的相关文章

Sicily 1936. Knight Moves

题目地址:1936. Knight Moves 思路: 这道题一开始不理解题意…orz...囧,看大神们理解的. 题意是说一个8*8的国际象棋,骑士以马的形式走动(“日”字型),指定两个点,输出最小的步骤. 可以利用广度搜索解决. 具体代码如下: 1 #include <iostream> 2 #include <queue> 3 #include <cstring> 4 #include <string> 5 using namespace std; 6

Sicily 1350. Piggy banks 解题报告

题目:1350. Piggy banks 思路: 首先把每个钥匙的位置存进key_positions[]中,然后从第一个bank开始,用不同的color给它们分组.比如第一个bank的钥匙在第二个bank中,那么可以直接先开第二个,第二个钥匙在第四个bank中,同样可以先开第四个,以此类推,直到某个钥匙出现在前面的同一组的某个bank中则需要打破一个.visited数组初始化为0,然后访问过后标记为颜色的编号.第21行visited[cur] == color只有找到颜色相同即在同一组的才需要打

Sicily 1046. Plane Spotting 解题报告

1046_Plane_Spotting 题目链接: http://soj.me/1046 题目大意: 给出序号为1,2,3...的时间段和每段时间上出现的飞机次数,找出几个连续的时间段,如2-5,其中持续的长度要大于或者等于题目要求.按照以下的要求来筛选出几个最优的时间段,如果达到要求的数量不够则全部输出,符合以下要求视为时间段p1优于p2: p1平均每段时间出现的飞机数大于p2,要求精度是double 平均每段时间出现飞机数一样,但是p1的持续时间比p2长 平均每段时间出现飞机数一样且持续时间

Sicily 1940. Ordering Tasks 解题报告

1940_Ordering_Tasks 题目链接: http://soj.me/1940 题目大意: 输入n和m,n代表任务的个数,m代表任务间先后关系的个数.后面输入m个先后关系,比如1 4表示任务1要在任务4之前完成.找到一种完成所有任务的顺序,满足所有要求的先后顺序,有多个解时要求输出字典序最小的. 思路: 拓扑排序问题,但是要求输出字典序最小的.输入实际上是一个有向图,建立一个数组inDegree记录每个任务之前要完成的任务,用vector数组记录每个任务指向的任务.开一个最小优先队列r

Sicily 1151. 魔板 解题报告

1151_魔板 题目链接: http://soj.me/1151 题目大意: 初始矩阵为: 1 2 3 4 8 7 6 5 有A,B,C三种操作方式来变化矩阵,给定目标矩阵,求要经过多少步能得到目标矩阵,超过步数限制误解则输出-1 思路: 为了操作简单直接用了string来存储矩阵,初始直接为"12348765",每一个状态经过三种变化可以产生三种新的状态,因此可以用宽度优先搜索来查找目标状态.因为最后还要输出变化的过程,所以对于每一个过程状态都要记录下由初始矩阵变化来的步骤.为了方便

Sicily 1090. Highways 解题报告

题目链接:Sicily 1090 思路: 简单的最小生成树问题,这里用prim算法即可.用visited数组记录每个结点是否已经被访问,即是否已经在最小生成树中.每次从不在最小生成树中的结点中取出一个key值最小的结点放入生成树中,key值表示结点到已经在生成树中点集合的最小距离.每次加入一个结点后更新与它相邻的结点的key值. 代码: #include <iostream> #include <queue> #include <stdio.h> #include &l

Sicily 1308. Dependencies among J 解题报告

题目:1308. Dependencies among J 思路: 比较简单的一道题,要知道m最早完成的时间,只需要找出所有需要在m之前完成的工作,将它们的完成时间加起来即可.这里使用vector的数组存储每个结点的邻接点,从结点m开始,依次宽度优先搜索m的每个邻接点...数组visited记录每个结点是否被访问过,遇到已经访问过的结点直接跳过. 读取的时候一开始没有找到解决办法,要读取一行的数字,并且要判断是否换行,可以首先读取第一个数即完成时间,然后用getchar读取一个字符,如果是'\n

Sicily Knight Moves(BFS)

1000. Knight Moves                       Time Limit: 1sec    Memory Limit:32MB Description A friend of you is doing research on the Traveling Knight Problem (TKP) where you are to find the shortest closed tour of knight moves that visits each square

poj分类解题报告索引

图论 图论解题报告索引 DFS poj1321 - 棋盘问题 poj1416 - Shredding Company poj2676 - Sudoku poj2488 - A Knight's Journey poj1724 - ROADS(邻接表+DFS) BFS poj3278 - Catch That Cow(空间BFS) poj2251 - Dungeon Master(空间BFS) poj3414 - Pots poj1915 - Knight Moves poj3126 - Prim