#62-【暴力dfs】棋盘

版权声明:反正也没有人会转,下一个 https://blog.csdn.net/drtlstf/article/details/82054324

Description

 

题目描述

        有一个m × m的棋盘,棋盘上每一个格子可能是红色、黄色或没有任何颜色的。你现在要从棋盘的最左上角走到棋盘的最右下角。

任何一个时刻,你所站在的位置必须是有颜色的(不能是无色的), 你只能向上、 下、左、 右四个方向前进。当你从一个格子走向另一个格子时,如果两个格子的颜色相同,那你不需要花费金币;如果不同,则你需要花费 1 个金币。

        另外, 你可以花费 2 个金币施展魔法让下一个无色格子暂时变为你指定的颜色。但这个魔法不能连续使用, 而且这个魔法的持续时间很短,也就是说,如果你使用了这个魔法,走到了这个暂时有颜色的格子上,你就不能继续使用魔法; 只有当你离开这个位置,走到一个本来就有颜色的格子上的时候,你才能继续使用这个魔法,而当你离开了这个位置(施展魔法使得变为有颜色的格子)时,这个格子恢复为无色。

现在你要从棋盘的最左上角,走到棋盘的最右下角,求花费的最少金币是多少?

 

输入格式:

        数据的第一行包含两个正整数 m, n,以一个空格分开,分别代表棋盘的大小,棋盘上有颜色的格子的数量。

接下来的 n 行,每行三个正整数 x, y, c, 分别表示坐标为( x, y)的格子有颜色 c。

其中 c=1 代表黄色, c=0 代表红色。 相邻两个数之间用一个空格隔开。 棋盘左上角的坐标为( 1, 1),右下角的坐标为( m, m)。

棋盘上其余的格子都是无色。保证棋盘的左上角,也就是( 1, 1) 一定是有颜色的。

输出格式:

        输出一行,一个整数,表示花费的金币的最小值,如果无法到达,输出-1。

 

 

Sample Input

输入样例#1: 
5 7
1 1 0
1 2 0
2 2 1
3 3 1
3 4 0
4 4 1
5 5 0

输入样例#2:
5 5
1 1 0
1 2 0
2 2 1
3 3 1
5 5 0

Sample Output

输出样例#1:
8
输出样例#2:
-1

HINT

 

输入输出样例 1 说明

 

从( 1, 1)开始,走到( 1, 2)不花费金币

从( 1, 2)向下走到( 2, 2)花费 1 枚金币

从( 2, 2)施展魔法,将( 2, 3)变为黄色,花费 2 枚金币

从( 2, 2)走到( 2, 3)不花费金币

从( 2, 3)走到( 3, 3)不花费金币

从( 3, 3)走到( 3, 4)花费 1 枚金币

从( 3, 4)走到( 4, 4)花费 1 枚金币

从( 4, 4)施展魔法,将( 4, 5)变为黄色,花费 2 枚金币,

从( 4, 4)走到( 4, 5)不花费金币

从( 4, 5)走到( 5, 5)花费 1 枚金币

共花费 8 枚金币。

输入输出样例 2 说明

 

从( 1, 1)走到( 1, 2),不花费金币

从( 1, 2)走到( 2, 2),花费 1 金币

施展魔法将( 2, 3)变为黄色,并从( 2, 2)走到( 2, 3)花费 2 金币

从( 2, 3)走到( 3, 3)不花费金币

从( 3, 3)只能施展魔法到达( 3, 2),( 2, 3),( 3, 4),( 4, 3)

而从以上四点均无法到达( 5, 5),故无法到达终点,输出-1

数据规模与约定

对于 30%的数据, 1 ≤ m ≤ 5, 1 ≤ n ≤ 10。

对于 60%的数据, 1 ≤ m ≤ 20, 1 ≤ n ≤ 200。

对于 100%的数据, 1 ≤ m ≤ 100, 1 ≤ n ≤ 1,000。

好吧......上课考试时爆50了(早知道不要用SPFA......)

再改成暴力45分(......)

再检查,发现没有使用魔法的flag是0,而有魔法时的flag是0或1......然后爆40......

再看,发现主函数调用dfs进去flag竟然没有设成-1(悲剧了......)......

改成-1,A了。

代码:

#include <iostream>
#include <cstring>

#define SIZE 101

using namespace std;

int a[SIZE][SIZE], best[SIZE][SIZE], INF[1], n;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

void dfs(int x, int y, int dis, int flag) // 暴力深搜
{
	int i, r, c;
	
	if (dis >= best[x][y])
	{
		return;
	}
	best[x][y] = dis;
	if (~flag) // 有魔法
	{
		for (i = 0; i < 4; ++i)
		{
			r = x + dx[i];
			c = y + dy[i];
			if (((!r) || (r > n)) || ((!c) || (c > n)))
			{
				continue;
			}
			if (~a[r][c])
			{
				dfs(r, c, dis + ((flag == a[r][c]) ? 0 : 1), -1);
			}
		}
		return;
	}
	for (i = 0; i < 4; ++i) // 没有魔法
	{
		r = x + dx[i];
		c = y + dy[i];
		if (((!r) || (r > n)) || ((!c) || (c > n)))
		{
			continue;
		}
		if (~a[r][c])
		{
			dfs(r, c, dis + ((a[x][y] == a[r][c]) ? 0 : 1), -1);
		}
		else
		{
			dfs(r, c, dis + 2, a[x][y]);
		}
	}
	
	return;
}

int main(int argc, char** argv)
{
	int m, x, y;
	
	memset(a, -1, sizeof (a));
	
	scanf("%d%d", &n, &m);
	while (m--)
	{
		scanf("%d%d", &x, &y);
		scanf("%d", &a[x][y]); // 不能用scanf("%d%d%d", &x, &y, &a[x][y])!会错!(快读x = read(), y = read(), a[x][y] = read()是可以的......)
	}
	
	memset(best, 127, sizeof (best));
	memset(INF, 127, sizeof (INF));
	dfs(1, 1, 0, -1);
	
	if (best[n][n] == INF[0])
	{
		printf("-1");
	}
	else
	{
		printf("%d", best[n][n]);
	}
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/drtlstf/article/details/82054324
62-