蓝桥杯算法训练合集一 1.印章2.拿金币3.数字游戏4.无聊的逗5.礼物
创始人
2024-05-01 09:54:54
0

目录

1.印章(动态规划)

2.拿金币(动态规划)

3.数字游戏(搜索)

4.无聊的逗(状态搜索)

5.礼物(二分法和前缀和)


1.印章(动态规划)

问题描述

共有n种图案的印章,每种图案的出现概率相同。小A买了m张印章,求小A集齐n种印章的概率。

输入格式

一行两个正整数n和m

输出格式

一个实数P表示答案,保留4位小数。

样例输入

2 3

样例输出

0.7500

数据规模与约定

1≤n,m≤20

示例代码

#include 
#include
#include
using namespace std;
int main() {int n, m;float dp[21][21], p, temp = 0;//dp[i][j]为抽i个印章能凑齐j种印章的几率cin >> n >> m;p = float(1) / n;//只抽一个印章但抽到某一个特定印章的几率if (m < n) {//抽的印章数小于印章种类数,则这种几率为0cout << setprecision(4) << fixed << temp << endl;return 0;}dp[1][1] = 1;//只抽一个印章肯定能凑齐一种印章for (int i = 2; i <= m; i++) {//抽i个印章凑齐1种印章的几率,保证后面的i-1个印章抽的和第一个一样dp[i][1] = dp[i - 1][1] * p;}for (int j = 2; j <= m; j++) {for (int i = 2; i <= j; i++) {//抽m个印章凑齐i种印章的几率if (j == i) {//如果要抽的印章数和凑齐的印章数相等,则抽到的每一个印章都和之前的不一样dp[j][i] = dp[j - 1][i - 1] * ((n + 1 - i)) * p;}else {//否则可能是 抽到的最后一个印章和之前抽到的任意一个印章相同 以及 抽到的最后一个印章和之前的任意一个印章都不相同dp[j][i] = dp[j - 1][i] * i * p + dp[j - 1][i - 1] * (n + 1 - i) * p;}}}cout << setprecision(4) << fixed << dp[m][n] << endl;return 0;
}

2.拿金币(动态规划)

问题描述

有一个N x N的方格,每一个格子都有一些金币,只要站在格子里就能拿到里面的金币。你站在最左上角的格子里,每次可以从一个格子走到它右边或下边的格子里。请问如何走才能拿到最多的金币。

输入格式

第一行输入一个正整数n。
以下n行描述该方格。金币数保证是不超过1000的正整数。

输出格式

最多能拿金币数量。

样例输入

3
1 3 3
2 2 2
3 1 2

样例输出

11

数据规模与约定

n<=1000

示例代码

#include 
#include
#include
int dp[1001][1001];
using namespace std;
int main() {int n;cin >> n;for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {cin >> dp[i][j];}}for (int i = 2; i <= n; i++) {//对第一行进行处理,只能向右走dp[i][1] += dp[i - 1][1];}for (int i = 2; i <= n; i++) {//对第一列进行处理,只能向下走dp[1][i] += dp[1][i - 1];}for (int i = 2; i <= n; i++) {for (int j = 2; j <= n; j++) {dp[i][j] += max(dp[i - 1][j], dp[i][j - 1]);//选取向下和向右走的最大值,这样局部的dp[i][j]就是最大值}}cout << dp[n][n];return 0;
}

3.数字游戏(搜索)

问题描述

给定一个1~N的排列a[i],每次将相邻两个数相加,得到新序列,再对新序列重复这样的操作,显然每次得到的序列都比上一次的序列长度少1,最终只剩一个数字。
例如:
3 1 2 4
4 3 6
7 9
16
现在如果知道N和最后得到的数字sum,请求出最初序列a[i],为1~N的一个排列。若有多种答案,则输出字典序最小的那一个。数据保证有解。

输入格式

第1行为两个正整数n,sum

输出格式

一个1~N的一个排列

样例输入

4 16

样例输出

3 1 2 4

数据规模与约定

0

示例代码

#include 
#include
using namespace std;
int main() {int n, a[11][11], b[11], sum, sum1 = 0, count = 1, count1 = 1;cin >> n;cin >> sum;for (int i = n; i >= 1; i--) {count1 *= i;}for (int i = 1; i <= n; i++) {b[i] = i;}if (n == 1) {//求每一项的系数,类似于(a+b)的n次方的各项系数,和杨辉三角形很像a[1][1] = 1;}/*n 各项系数1 12 1 13 1 2 14 1 3 3 15 1 4 6 4 1...............*/else if (n == 2) {a[2][1] = 1;a[2][2] = 1;}else {for (int i = 2; i <= n; i++) {for (int j = 1; j <= i; j++) {if (j == 1 || j == i) {a[i][j] = 1;}else {a[i][j] = a[i - 1][j - 1] + a[i - 1][j];}}}}while (sum1 != sum) {//当还未找到需要的数时sum1 = 0;//sum1为此次1-n数字的排序的相邻总和for (int i = 1; i <= n; i++) {sum1 += a[n][i] * b[i];}count++;if (count == count1) {//如果1-n之间的数字排序排完了还是没有找到,说明不存在对应的结果return 0;}next_permutation(b + 1, b + n + 1);//将1-n组成的数进行从小到大的排序}prev_permutation(b + 1, b + n + 1);//多做了一次next则要prev降序一次for (int i = 1; i <= n; i++) {cout << b[i] << " ";}return 0;
}

4.无聊的逗(状态搜索)

问题描述

逗志芃在干了很多事情后终于闲下来了,然后就陷入了深深的无聊中。不过他想到了一个游戏来使他更无聊。他拿出n个木棍,然后选出其中一些粘成一根长的,然后再选一些粘成另一个长的,他想知道在两根一样长的情况下长度最长是多少。

输入格式

第一行一个数n,表示n个棍子。第二行n个数,每个数表示一根棍子的长度。

输出格式

一个数,最大的长度。

样例输入

4
1 2 3 1

样例输出

3

数据规模与约定

n<=15

示例代码

#include
using namespace std;
int a[15];
int b[1 << 15] = { 0 };
int max(int a, int b) {if (a > b) {return a;}else {return b;}
}
int main() {int n, ans = 0;cin >> n;for (int i = 0; i < n; i++) {cin >> a[i];}for (int i = 0; i < (1 << n); i++) {//按照二进制来表示木棍选取情况 如1100表示选取的是第四根和第三根木棍,共2的n次方种选取情况for (int j = 0; j < n; j++) {if (i & (1 << j)) {//如果i放置的木棍中有第j根木棍  用与是因为二进制b[i] += a[j];}}}for (int i = 0; i < (1 << n); i++) {//先选取的木棍for (int j = 0; j < (1 << n); j++) {//后选取的木棍if (!(i & j) && b[i] == b[j]) {//如果不是同一种选取方式而且长度相同ans = max(ans, b[i]);}}}cout << ans;
}

5.礼物(二分法和前缀和)

问题描述

JiaoShou在爱琳大陆的旅行完毕,即将回家,为了纪念这次旅行,他决定带回一些礼物给好朋友。
在走出了怪物森林以后,JiaoShou看到了排成一排的N个石子。
这些石子很漂亮,JiaoShou决定以此为礼物。
但是这N个石子被施加了一种特殊的魔法。
如果要取走石子,必须按照以下的规则去取。
每次必须取连续的2*K个石子,并且满足前K个石子的重量和小于等于S,后K个石子的重量和小于等于S。
由于时间紧迫,Jiaoshou只能取一次。
现在JiaoShou找到了聪明的你,问他最多可以带走多少个石子。

输入描述

第一行两个整数N、S。
第二行N个整数,用空格隔开,表示每个石子的重量。

输出格式

第一行输出一个数表示JiaoShou最多能取走多少个石子。

样例输入

8 3
1 1 1 1 1 1 1 1

样例输出

6

样例解释

任意选择连续的6个1即可。

数据规模与约定

对于20%的数据:N<=1000
对于70%的数据:N<=100,000
对于100%的数据:N<=1000,000,S<=10^12,每个石子的重量小于等于10^9,且非负

示例代码

#include
#include
using namespace std;
int n;
long long s;
long long a[1000001], b[1000002] = { 0 };
bool inject(int c) {for (int i = c; i <= n - c; i++) {//i=c保证找到向左能有连续c个长度的石头,i<=n-c保证向右有连续c个长度的石头if (b[i] - b[i-c] <= s && b[c + i] - b[i] <= s) {//如果i左边的连续c个和右边连续c个石头的重量和都小于等于sreturn true;}}return false;//如果这个长度下都不符合
}
int main() {cin >> n >> s;for (int i = 1; i <= n; i++) {cin >> a[i];b[i] = b[i - 1] + a[i];//前缀和 b[n]-b[n-i]为 a[n-i+1]到a[n]之间的连续的和}int l = 1;int r = n;int k;while (l < r) {//当未找到时,l> 1;//二分法,取一半,(l+r)/2会造成死循环。。。。。。。。if (inject(k)) {//这个长度符合要求,可能有更大的长度l = k;}else {//这个长度不符合要求,长度要更小一些r = k - 1;}}cout <<2* l;
}

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...