蓝桥杯刷题第十九天
创始人
2025-06-01 15:18:20

第一题:灌溉

题目描述
小蓝负责花园的灌溉工作。
花园可以看成一个 n 行 m 列的方格图形。中间有一部分位置上安装有出水管。
小蓝可以控制一个按钮同时打开所有的出水管,打开时,有出水管的位置可以被认为已经灌溉好。
每经过一分钟,水就会向四面扩展一个方格,被扩展到的方格可以被认为已经灌溉好。即如果前一分钟某一个方格被灌溉好,则下一分钟它上下左右的四个方格也被灌溉好。
给定花园水管的位置,请问 k 分钟后,有多少个方格被灌溉好?
输入描述
输入的第一行包含两个整数 n,m。
第二行包含一个整数 t,表示出水管的数量。
接下来 t 行描述出水管的位置,其中第 i 行包含两个数 r,c 表示第 r 行第 c 列有一个排水管。
接下来一行包含一个整数 k。
其中,1≤n,m≤100,1≤t≤10,1≤k≤100。
输出描述
输出一个整数,表示答案。
输入输出样例
输入
3 6
2
2 2
3 4
1
输出
9

dfs思路,就是每次把有水的地方进行扩大

并且设置状态s,表示是第几次开始扩大的,这样每一次就能做到该次只扩大该一次的

#include
#include
using namespace std;const int N = 110;
int n, m, t, k;
int g[N][N];
int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, -1, 1};void dfs(int r, int c, int s){for(int i = 0; i < 4; i++){int x = dx[i] + r, y = dy[i] + c;if(x >= 1 && x <= n && y >= 1 && y <= m && g[x][y] == 0)g[x][y] = s + 1;}
}int main(){scanf("%d%d", &n, &m);scanf("%d", &t);while(t--){int a, b;scanf("%d%d", &a, &b);g[a][b] = 1;}scanf("%d", &k);int s = 1;while(s <= k){for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++)if(g[i][j] == s) {dfs(i, j, s);}s++;}int ans = 0;for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++)if(g[i][j] >= 1)ans++;cout<

第二题:小朋友崇拜圈

题目描述
班里 N 个小朋友,每个人都有自己最崇拜的一个小朋友(也可以是自己)。
在一个游戏中,需要小朋友坐一个圈,每个小朋友都有自己最崇拜的小朋友在他的右手边。
求满足条件的圈最大多少人?
小朋友编号为1,2,3,⋯N。
输入描述
输入第一行,一个整数 N(3接下来一行 N 个整数,由空格分开。
输出描述
要求输出一个整数,表示满足条件的最大圈的人数。
输入输出样例
输入
9
3 4 2 5 3 8 4 6 9
输出
4

dfs,状态有三个,当前位置,当前位置的崇拜者,人数

枚举每个位置

当人数大于总人数肯定是死循环了,return

当崇拜者等于枚举的当前位置,即构成一个崇拜圈

更新最大值

其余情况继续dfs

#include
using namespace std;const int N = 1e5 + 10;
int n, p[N];
int ans;void dfs(int u, int v, int t){if(t > n) return ;if(v == u) {ans = max(ans, t);return ;}dfs(u, p[v], t + 1);
}int main(){scanf("%d", &n);for(int i = 1; i <= n; i++) scanf("%d", &p[i]);for(int i = 1; i <= n; i++)dfs(i, p[i], 1);cout<

第三题:括号序列

题目描述
给定一个括号序列,要求尽可能少地添加若干括号使得括号序列变得合法,当添加完成后,会产生不同的添加结果,请问有多少种本质不同的添加结果。
两个结果是本质不同的是指存在某个位置一个结果是左括号,而另一个是右括号。
例如,对于括号序列 ((()(((),只需要添加两个括号就能让其合法,有以下几种不同的添加结果:()()()()()()、()(())()(())、(())()(())()、(()())(()()) 和 ((()))((()))。
输入描述
输入一行包含一个字符串 s,表示给定的括号序列,序列中只有左括号和右括号。
输出描述
输出一个整数表示答案,答案可能很大,请输出答案除以 1000000007 (即 109+7)的余数。
输入输出样例
输入
((()
输出
5

括号问题两个条件:

  1. 左括号等于右括号

  1. 左括号一定大于等于右括号的数量才能加

独立性:放置左右括号方案互相不影响

所以可以先左括号放,再进行右括号放置(相当于反着放左括号),这里翻转加左右变换得到反序列

状态:f[i,j]表示前i个括号,左括号比右括号多j个的方案数量

然后方案数量 f[0,0] = 1

集合:左括号,f[i][j] = f[i-1][j-1];

右括号,f[i][j] = f[i-1][j+1] + f[i][j-1]

还要取余MOD

#include
#include
#include
using namespace std;const int N =  5010, MOD = 1e9 + 7;
typedef long long LL;
char str[N];
LL f[N][N], n;LL call(){memset(f, 0, sizeof f);f[0][0] = 1;for(int i = 1; i <= n; i++){if(str[i] == '('){for(int j = 1; j <= n; j++)f[i][j] = f[i-1][j-1];}else{f[i][0] = (f[i-1][0] + f[i-1][1]) % MOD;for(int j = 1; j <= n; j++)f[i][j] = (f[i-1][j+1] + f[i][j-1]) % MOD;}}for(int i = 0; i <= n; i++)if(f[n][i])return f[n][i];return -1;
}int main(){scanf("%s", str + 1);n = strlen(str + 1);LL l = call();reverse(str + 1, str + 1 + n);for(int i = 1; i <= n; i++)if(str[i] == '(') str[i] = ')';else str[i] = '(';LL r = call();cout<

相关内容

热门资讯

投资者提问:请问董秘,当前中日... 投资者提问:请问董秘,当前中日关系陷入僵局乃至谷底之际,公司有规划更多使用国产光刻胶等材料来替代日系...
富德生命人寿咸阳中心支公司被罚... 12月16日金融一线消息,据咸阳金融监管分局行政处罚信息公开表显示,富德生命人寿保险股份有限公司咸阳...
市场监管总局:抓紧推进出台《互... 转自:北京日报客户端记者16日从市场监管总局获悉,市场监管总局正抓紧推进《互联网平台反垄断合规指引》...
天奇股份:锂电循环业务夯实产业... 12月16日,江西天奇金泰阁集团(简称“天奇金泰阁”)资本赋能发展大会在江西龙南举行。会上,天奇股份...
「侠客岛」他们用上了“AI分身...   炒股就看金麒麟分析师研报,权威,专业,及时,全面,助您挖掘潜力主题机会! (来源:海外网)来源...