P3956 [NOIP2017 普及组] 棋盘

P3956 [NOIP2017 普及组] 棋盘

题目

题目描述

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

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

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

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

输入格式

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

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

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

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

输出格式

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

思路

dfs

考虑到数据范围 dfs 可能会爆 于是考虑优化dfs

dfs(int x,int y,int cost,int color)

其中 x,y 均为坐标, cost 表示当前的答案, color 表示颜色

需要考虑使用魔法的过程,单独判断即可

CPP

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

int i,m,n,j,k,q,p,w;
int a[1100][1100];
int f[4]= {0,0,1,-1},ff[4]= {1,-1,0,0};
int minn=0x7fffffff;
int d[1100][1100];
bool bl[1100][1100];

void search(int x,int y,int c,int color) {
	if((x==n)&&(y==n)) {
		minn=min(c,minn);
		return;
	}
	for(int i=0; i<4; i++) {
		int p=x+f[i],q=y+ff[i];
		if((p<=n)&&(p>0)&&(q<=n)&&(q>0))
			if(bl[p][q])
				if(a[x][y]||a[p][q]) {
					if(a[p][q]==0) {
						if(c+2<d[p][q]) {
							bl[p][q]=0;
							d[p][q]=c+2,search(p,q,c+2,color);
							bl[p][q]=1;
						}
					} else {
						if((color==a[p][q])&&(c<d[p][q])) {
							bl[p][q]=0;
							d[p][q]=c,search(p,q,c,color);
							bl[p][q]=1;
						} else if((c+1<minn)&&(c+1<d[p][q])) {
							bl[p][q]=0;
							d[p][q]=c+1,search(p,q,c+1,a[p][q]);
							bl[p][q]=1;
						}
					}
				}
	}
}


int main() {
	scanf("%d%d",&n,&m);
	for(i=1; i<=n; i++)
		for(j=1; j<=n; j++) d[i][j]=0x7fffffff,a[i][j]=0,bl[i][j]=1;
	for(i=1; i<=m; i++) {
		scanf("%d%d%d",&q,&p,&w);
		a[q][p]=w+1; 
	}
	bl[1][1]=0;
	search(1,1,0,a[1][1]);
	if(minn==0x7fffffff) printf("-1");
	else printf("%d",minn);
	return 0;
}
posted @   Pass1on_W  阅读(105)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示