首页 > 其他分享 >【NOIP模拟题】我要的幸福 题解

【NOIP模拟题】我要的幸福 题解

时间:2023-07-31 15:24:26浏览次数:40  
标签:bfs int 题解 Zyh 模拟题 我要 向右走 权值 include

1.题意简述

\(Zyh\) 相信自己想要的幸福在不远处。然而,\(zyh\) 想要得到这幸福,还需要很长的一段路。

\(Zyh\) 坚持认为整个人生可以抽象为一个 \(n * m\) 的棋盘。左上角的格子为 \((1,1)\),右下角的格子为 \((n,m)\)。整个棋盘上的格子都有不同的事件,因为生活的多姿多彩,事件的权值\(A_{(i, j)}\)都两两不同。

不幸的是,在整个人生中有若干个极其黑暗的事件,它们的权值 \(A_{(i, j)} = 0\)。更进一步说,对于 \(A_{(i, j)} > 0\) 的事件,权值两两不同。 \(Zyh\) 站在人生的起点 \((1,1)\),他想要走向人生的巅峰 \((n,m)\)。

\(Zyh\) 认为人只能前进,即若 \(Zyh\) 站在 \((a,b)\),他只能走向 \((a,b+1)\) 或者 \((a+1,b)\)。

并且 \(Zyh\) 认为黑暗的事件是绝对不可以触碰的,因为一旦经历就会坠入万丈深渊。

\(Zyh\) 会将自己所经历的事件的权值依次写出,形成一个 \(n+m-1\) 的序列。

\(Zyh\) 想知道其中字典序最小的序列是什么。

若是人生过于艰难,没有一个合法序列,就输出 Oh,the life is too difficult!

总结:给定一个n*m的矩阵,矩阵中每个点有一个权值。要求所有从1走到n且不经过权值为0的点的字典序最小的路径序列。

2.样例解释

我们先画一组样例:

3 3
1 3 4
7 9 0
5 6 8
1 3 9 6 8

在图中我们不难发现:矩阵中九个元素,\(4\) 和 \(0\) 是肯定走不了的。

于是我们在剩下七个点中从 \(1\) 出发,在向下和向右两种策略中选择字典序更小的向右 (权值为 \(3\))。

然后我们发现在 \(3\) 这个点只能向下走,于是我们走到权值为 \(6\) 的点,最后发现不能向下走,所以向右走到终点。

3.思路

结合样例,我们不难得出以下思路:

  • 1.从 \((n, m)\) 开始跑一遍 \(bfs\),标记好一定不能走的点。

  • 2.判断 \(vis[1][1]\) 是否为逻辑假,如果是,说明无解。

  • 3.从 \((1, 1)\) 开始枚举每个点,如果有两种策略,就选择权值较小的点走,直到走到 \((n, m)\) 为止。

4.注意事项

  • 1.由于题中顺着走是向下和向右走,所以倒着跑 \(bfs\) 时就要变为向上和向左走;

  • 2.由于代码实现时有差距,最后可能要再输出一遍 \(a_{(n,m)}\) 的值,不要漏掉了!!!

5.代码实现

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#define int long long

using namespace std;

#define N 1010
#define For(i,j,k) for(int i=j;i<=k;i++)
#define IOS ios::sync_with_stdio(),cin.tie(),cout.tie()

int a[N][N], n, m, vis[N][N];
int dx[2] = {0, -1}, dy[2] = {-1, 0}; //存行动方式的数组
struct no {
	int x, y;
};queue <no> q;

void bfs (int x, int y) {
	q.push({x, y});
	vis[x][y] = 1; //将(n,m)打上逻辑真
	
	while (!q.empty ()) {
		no res = q.front ();//取出队头元素
		q.pop ();
		
		for (int i = 0; i <= 1; i ++) {
			int t1 = res.x + dx[i], t2 = res.y + dy[i]; //模拟下一步
			
			if (t1 >= 1 && t1 <= n && t2 >= 1 && t2 <= m && vis[t1][t2] == 0 && a[t1][t2] != 0) {
			//如果下一步还在矩阵范围内,且是还没被用过的非0的点,则走到 (t1,t2) 这个点
				q.push ({t1, t2});
				vis[t1][t2] = 1;
			}
		}
	}
	
	if (vis[1][1] == 0) { //如果 (1, 1) 是逻辑假,即从 (n, m) 走不到 (1, 1) 这个点
		cout << "Oh,the life is too difficult!" << endl;
		exit (0); //输出并结束程序。
	}
}

signed main () {
	cin >> n >> m;
	For (i, 1, n) {
		For (j, 1, m) {
			cin >> a[i][j];
		}
	}
	
	bfs (n, m);
	
	int x = 1, y = 1;
	while (x != n || y != m) {
		cout << a[x][y] << " "; //从(1, 1)开始输出
		if (vis[x][y + 1] == 0 || y >= m) { //如果不能向下走,就向右走
			x ++;
		} else if (vis[x + 1][y] == 0 || x >= n) { //如果不能向右走,就向下走
			y ++;
		} else { //如果都可以,取权值较小的走
			if (a[x][y + 1] >= a[x + 1][y]) x ++;
			else y ++;
		}
	}
	
	cout << a[n][m] << endl; //别忘了输出终点
	return 0;
}

标签:bfs,int,题解,Zyh,模拟题,我要,向右走,权值,include
From: https://www.cnblogs.com/linbaicheng/p/17593503.html

相关文章

  • 2009NOIP普及组 题解
    第一题第二题\(一二题太简单就不在此处提了\)\(直接看到\)第三题细胞分裂题目大意\(有m1^{m2}个试管和n种细胞,第i种细胞初始有1个,每过1秒每一个会分裂成a_i个\)\(当有某种细胞可以平均分到试管中时开始实验,求开始实验的\)时间\((顺便说一下,我一开始没看到是时间,以为是求哪......
  • 洛谷-P9485 题解
    写在前面:这是蒟蒻交的第一篇绿题题解(大祭),因为线性做法比较难想,本篇会着重讲述用RMQ问题求解,并尽可能用清晰明了的图片和简易的文字讲明白。正文最坏时间复杂度:\(\mathcal{O}(\sumn+\log\sumn)\)在求解之前,先让我们想个问题,如何求解积水格数?再简单点,对于每个\(i\),其积水......
  • AcWing 4797. 移动棋子题解
    算出数值为\(1\)的点离\((3,3)\)的距离即可。#include<iostream>#include<cstring>#include<algorithm>usingnamespacestd;intmain(){intpx=-1,py=-1;for(inti=1;i<=5;i++){for(intj=1;j<=5;j++)......
  • AcWing 4798. 打怪兽题解
    可以从\(1\)枚举到\(n\)表示要打多少个怪兽。因为你要打\(t\)个怪兽,并不管顺序,所以我们可以对\([1,t]\)这一段进行排序,然后计算\(a[t],a[t-2],a[t-4],\dots\)即可(因为你要干掉第\(t\)个怪兽的时候,必须要使用\(a[t]\)的法力值,因为排过序,所以连着\(t-1\)......
  • 【题解】[ABC312E] Tangency of Cuboids(adhoc)
    【题解】[ABC312E]TangencyofCuboids少见的at评分\(2000+\)的ABCE题,非常巧妙的一道题。特别鸣谢:@dbxxx给我讲解了他的完整思路。题目链接ABC312E-TangencyofCuboids题意概述给定三维空间中的\(n\)个长方体,每个长方体以其一条体对角线的两个端点的坐标形式......
  • 0730小马拉松 题解
    T358782阶乘数学。测试点\(1\sim3\):longlong暴力阶乘。预期30分。测试点\(4\sim5\):暴力试除,找出因子\(5\)的个数。预期50分。测试点\(6\sim7\):考虑这样一个程序:while(x)x/=5,cnt+=x;即求出有多少个数是\(5\)的倍数,\(25\)的倍数,\(125\)的倍数......加起来......
  • P3375 【模板】KMP 字符串匹配 题解
    前言狗屁不是,建议别看!!! 题目链接P3375【模板】KMP字符串匹配-洛谷|计算机科学教育新生态(luogu.com.cn) 分析先给个例子s1:ABCABCABBs2:ABCABB若使用朴素算法匹配,当匹配到s1:ABCABCABBs2:ABCABB时,朴素算法会跳出,然后匹配下一位。最终匹配到s1:ABCABCABBs2:......
  • 洛谷 P9489 ZHY 的表示法 题解
    Description给定\(\{x_n\}\),\(y\)为任意实数,求出在\([l,r]\)内\(\displaystyle\sum_{i=1}^{n}\lfloor\dfrac{y}{x_i}\rfloor\)有多少种取值。link:https://www.luogu.com.cn/problem/P9489Solution可以表示出的取值一定能被为某个\(x_i\)的倍数的\(y\)表示出。根据......
  • [ABC312] 题解 [D~Ex]
    [ABC312]题解[D~Ex]D-CountBracketSequences一个括号序列\(s\)包含(,),?,?可以填任意括号,问你填完后有多少种合法序列方式。这是一个Classical的括号序列DP,使用这个状态表示可以解决很多括号序列问题:\(dp[i][j]\)表示已经摆好了前\(i\)个字符,有\(j\)个没......
  • BZOJ 4321 queue2 题解
    在硬盘里翻到了当时没推完的这个题,今天补完了最后几步。题目链接:https://hydro.ac/d/bzoj/p/4321对任意相邻两个元素差的绝对值不为\(1\)的\(n\)阶排列计数。\(\mathcal{O}(n^2)\)做法是考虑按照值域由小到大逐步插入,记录\(f_{i,j}\)为长度为\(i\)的排列,一共有\(j\)......