第23次CCF计算机软件能力认证

1. 数组推导

A 1 , A 2 , ⋯ , A n A_1, A_2, \cdots, A_n A1,A2,,An 是一个由 n n n自然数(即非负整数)组成的数组。

在此基础上,我们用数组 B 1 ⋯ B n B_1 \cdots B_n B1Bn 表示 A A A 的前缀最大值。

B i = max ⁡ { A 1 , A 2 , ⋯ , A i } B_i = \max \{ A_1, A_2, \cdots, A_i \} Bi=max{A1,A2,,Ai}

如上所示, B i B_i Bi 定义为数组 A A A 中前 i i i 个数的最大值。

根据该定义易知 A 1 = B 1 A_1 = B_1 A1=B1,且随着 i i i 的增大, B i B_i Bi 单调不降。

此外,我们用 s u m = A 1 + A 2 + ⋯ + A n sum = A_1 + A_2 + \cdots + A_n sum=A1+A2++An 表示数组 A A A n n n 个数的总和。

现已知数组 B B B,我们想要根据 B B B 的值来反推数组 A A A

显然,对于给定的 B B B A A A 的取值可能并不唯一。

试计算,在数组 A A A 所有可能的取值情况中, s u m sum sum 的最大值和最小值分别是多少?

输入格式

输入的第一行包含一个正整数 n n n

输入的第二行包含 n n n 个用空格分隔的自然数 B 1 , B 2 , ⋯ , B n B_1, B_2, \cdots, B_n B1,B2,,Bn

输出格式

输出共两行。

第一行输出一个整数,表示 s u m sum sum 的最大值。

第二行输出一个整数,表示 s u m sum sum 的最小值。

数据范围

50 % 50\% 50% 的测试数据满足数组 B B B 单调递增,即 0 < B 1 < B 2 < ⋯ < B n < 1 0 5 0 < B_1 < B_2 < \cdots < B_n < 10^{5} 0<B1<B2<<Bn<105
全部的测试数据满足 n ≤ 100 n \le 100 n100 且数组 B B B 单调不降,即 0 ≤ B 1 ≤ B 2 ≤ ⋯ ≤ B n ≤ 1 0 5 0 \le B_1 \le B_2 \le \cdots \le B_n \le 10^{5} 0B1B2Bn105

输入样例1:
6
0 0 5 5 10 10
输出样例1:
30
15
样例1解释

数组 A A A 的可能取值包括但不限于以下三种情况。

  • 情况一: A = [ 0 , 0 , 5 , 5 , 10 , 10 ] A = [0, 0, 5, 5, 10, 10] A=[0,0,5,5,10,10]
  • 情况二: A = [ 0 , 0 , 5 , 3 , 10 , 4 ] A = [0, 0, 5, 3, 10, 4] A=[0,0,5,3,10,4]
  • 情况三: A = [ 0 , 0 , 5 , 0 , 10 , 0 ] A = [0, 0, 5, 0, 10, 0] A=[0,0,5,0,10,0]

其中第一种情况 s u m = 30 sum = 30 sum=30 为最大值,第三种情况 s u m = 15 sum = 15 sum=15 为最小值。

输入样例2:
7
10 20 30 40 50 60 75
输出样例2:
285
285
样例2解释

A = [ 10 , 20 , 30 , 40 , 50 , 60 , 75 ] A = [10, 20, 30, 40, 50, 60, 75] A=[10,20,30,40,50,60,75] 是唯一可能的取值,所以 s u m sum sum 的最大、最小值均为 285 285 285

变则取(a[i-1]<a[i] ,ans+=a[i]),不变 min 取0 , max也取(ans+=a[i])

2.非零段划分

A 1 , A 2 , ⋯ , A n A_1, A_2, \cdots, A_n A1,A2,,An 是一个由 n n n 个自然数(非负整数)组成的数组。

我们称其中 A i , ⋯ , A j A_i, \cdots, A_j Ai,,Aj 是一个非零段,当且仅当以下条件同时满足:

  • 1 ≤ i ≤ j ≤ n 1 \le i \le j \le n 1ijn
  • 对于任意的整数 k k k,若 i ≤ k ≤ j i \le k \le j ikj,则 A k > 0 A_k > 0 Ak>0
  • i = 1 i = 1 i=1 A i − 1 = 0 A_{i-1} = 0 Ai1=0
  • j = n j = n j=n A j + 1 = 0 A_{j+1} = 0 Aj+1=0

下面展示了几个简单的例子:

  • A = [ 3 , 1 , 2 , 0 , 0 , 2 , 0 , 4 , 5 , 0 , 2 ] A = [3, 1, 2, 0, 0, 2, 0, 4, 5, 0, 2] A=[3,1,2,0,0,2,0,4,5,0,2] 中的 4 4 4 个非零段依次为 [ 3 , 1 , 2 ] [3, 1, 2] [3,1,2] [ 2 ] [2] [2] [ 4 , 5 ] [4, 5] [4,5] [ 2 ] [2] [2]
  • A = [ 2 , 3 , 1 , 4 , 5 ] A = [2, 3, 1, 4, 5] A=[2,3,1,4,5] 仅有 1 1 1 个非零段;
  • A = [ 0 , 0 , 0 ] A = [0, 0, 0] A=[0,0,0] 则不含非零段(即非零段个数为 0 0 0)。

现在我们可以对数组 A A A 进行如下操作:任选一个正整数 p p p,然后将 A A A 中所有小于 p p p 的数都变为 0 0 0

试选取一个合适的 p p p,使得数组 A A A 中的非零段个数达到最大。

若输入的 A A A 所含非零段数已达最大值,可取 p = 1 p=1 p=1,即不对 A A A 做任何修改。

输入格式

输入的第一行包含一个正整数 n n n

输入的第二行包含 n n n 个用空格分隔的自然数 A 1 , A 2 , ⋯ , A n A_1, A_2, \cdots, A_n A1,A2,,An

输出格式

仅输出一个整数,表示对数组 A A A 进行操作后,其非零段个数能达到的最大值。

数据范围

70 % 70\% 70% 的测试数据满足 n ≤ 1000 n \le 1000 n1000
全部的测试数据满足 n ≤ 5 × 1 0 5 n \le 5 \times 10^{5} n5×105,且数组 A A A 中的每一个数均不超过 1 0 4 10^{4} 104

输入样例1:
11
3 1 2 0 0 2 0 4 5 0 2
输出样例1:
5
样例1解释

p = 2 p = 2 p=2 时, A = [ 3 , 0 , 2 , 0 , 0 , 2 , 0 , 4 , 5 , 0 , 2 ] A = [3, 0, 2, 0, 0, 2, 0, 4, 5, 0, 2] A=[3,0,2,0,0,2,0,4,5,0,2] 5 5 5 个非零段依次为 [ 3 ] [3] [3] [ 2 ] [2] [2] [ 2 ] [2] [2] [ 4 , 5 ] [4, 5] [4,5] [ 2 ] [2] [2];此时非零段个数达到最大。

输入样例2:
14
5 1 20 10 10 10 10 15 10 20 1 5 10 15
输出样例2:
4
样例2解释

p = 12 p = 12 p=12 时, A = [ 0 , 0 , 20 , 0 , 0 , 0 , 0 , 15 , 0 , 20 , 0 , 0 , 0 , 15 ] A = [0, 0, 20, 0, 0, 0, 0, 15, 0, 20, 0, 0, 0, 15] A=[0,0,20,0,0,0,0,15,0,20,0,0,0,15] 4 4 4 个非零段依次为 [ 20 ] [20] [20] [ 15 ] [15] [15] [ 20 ] [20] [20] [ 15 ] [15] [15];此时非零段个数达到最大。

输入样例3:
3
1 0 0
输出样例3:
1
样例3解释

p = 1 p = 1 p=1 时, A = [ 1 , 0 , 0 ] A = [1, 0, 0] A=[1,0,0],此时仅有 1 1 1 个非零段 [ 1 ] [1] [1],非零段个数达到最大。

输入样例4:
3
0 0 0
输出样例4:
0
样例4解释

无论 p p p 取何值, A A A 都不含有非零段,故非零段个数至多为 0 0 0

记录每一个数的下标 , 从小到大每一次取值都把相应的数=0,多了个山峰就把初始解++,融合了两个山峰为一个就 --

#include <iostream>
#include <algorithm>
#include <cstring>
#include <set>using namespace std;const int N = 5e5 + 10;
int n, A[N], res;
set<int>a;
vector<int>h[N];int main(){cin >> n;for(int i = 1; i <= n; i ++){cin >> A[i];h[A[i]].push_back(i);//存储A中每一个数所出现的位置,以便后续直接访问a.insert(A[i]);//去重排序}int p = 1 , ans = 0;for(int i = 1 ; i <= n ; i++) if(!A[i - 1] && A[i]) ans ++ ;for(auto t : a){for(int j = p; j <= t; j ++){for(auto x : h[j]) {A[x] = 0;if(A[x-1] != 0 && A[x+1] != 0)ans ++; //多了个岛,++else if(A[x - 1] == 0 && A[x + 1] == 0 ) ans --;//少了个岛 --//其余的情况不变}}res = max(res, ans);p = t + 1;}cout << res;return 0;}

4. 收集卡牌

小林在玩一个抽卡游戏,其中有 n n n 种不同的卡牌,编号为 1 1 1 n n n

每一次抽卡,她获得第 i i i 种卡牌的概率为 p i p_i pi

如果这张卡牌之前已经获得过了,就会转化为一枚硬币。

可以用 k k k 枚硬币交换一张没有获得过的卡。

小林会一直抽卡,直至集齐了所有种类的卡牌为止,求她的期望抽卡次数。

如果你给出的答案与标准答案的绝对误差不超过 1 0 − 4 10^{-4} 104,则视为正确。

提示:聪明的小林会把硬币攒在手里,等到通过兑换就可以获得剩余所有卡牌时,一次性兑换并停止抽卡。

输入格式

输入共两行。

第一行包含两个用空格分隔的正整数 n , k n, k n,k,第二行给出 p 1 , p 2 , … , p n p_1, p_2, \dots, p_n p1,p2,,pn,用空格分隔。

输出格式

输出共一行,一个实数,即期望抽卡次数。

数据范围

对于 20 % 20\% 20% 的数据,保证 1 ≤ n , k ≤ 5 1 \leq n, k \leq 5 1n,k5
对于另外 20 % 20\% 20% 的数据,保证所有 p i p_i pi 是相等的。
对于 100 % 100\% 100% 的数据,保证 1 ≤ n ≤ 16 , 1 ≤ k ≤ 5 1 \leq n \leq 16, 1 \leq k \leq 5 1n16,1k5,所有的 p i p_i pi 满足 p i ≥ 1 10000 p_i \geq \frac{1}{10000} pi100001,且 ∑ i = 1 n p i = 1 \sum_{i=1}^{n} p_i=1 i=1npi=1
注意,本题在官网必须保留 10 10 10 位小数才能通过(可能是没加SPJ),在本网站无此问题,只要满足你给出的答案与标准答案的绝对误差不超过 1 0 − 4 10^{-4} 104,则视为正确。

输入样例1:
2 2
0.4 0.6
输出样例1:
2.52
样例1解释

共有 2 2 2 种卡牌,不妨记为 A A A B B B,获得概率分别为 0.4 0.4 0.4 0.6 0.6 0.6 2 2 2 枚硬币可以换一张卡牌。下面给出各种可能出现的情况:

  • 第一次抽卡获得 A A A,第二次抽卡获得 B B B,抽卡结束,概率为 0.4 × 0.6 = 0.24 0.4 \times 0.6 = 0.24 0.4×0.6=0.24,抽卡次数为 2 2 2
  • 第一次抽卡获得 A A A,第二次抽卡获得 A A A,第三次抽卡获得 B B B,抽卡结束,概率为 0.4 × 0.4 × 0.6 = 0.096 0.4 \times 0.4 \times 0.6 = 0.096 0.4×0.4×0.6=0.096,抽卡次数为 3 3 3
  • 第一次抽卡获得 A A A,第二次抽卡获得 A A A,第三次抽卡获得 A A A,用硬币兑换 B B B,抽卡结束,概率为 0.4 × 0.4 × 0.4 = 0.064 0.4 \times 0.4 \times 0.4 = 0.064 0.4×0.4×0.4=0.064,抽卡次数为 3 3 3
  • 第一次抽卡获得 B B B,第二次抽卡获得 A A A,抽卡结束,概率为 0.6 × 0.4 = 0.24 0.6 \times 0.4 = 0.24 0.6×0.4=0.24,抽卡次数为 2 2 2
  • 第一次抽卡获得 B B B,第二次抽卡获得 B B B,第三次抽卡获得 A A A,抽卡结束,概率为 0.6 × 0.6 × 0.4 = 0.144 0.6 \times 0.6 \times 0.4 = 0.144 0.6×0.6×0.4=0.144,抽卡次数为 3 3 3
  • 第一次抽卡获得 B B B,第二次抽卡获得 B B B,第三次抽卡获得 B B B,用硬币兑换 A A A,抽卡结束,概率为 0.6 × 0.6 × 0.6 = 0.216 0.6 \times 0.6 \times 0.6 = 0.216 0.6×0.6×0.6=0.216,抽卡次数为 3 3 3

因此答案是 0.24 × 2 + 0.096 × 3 + 0.064 × 3 + 0.24 × 2 + 0.144 × 3 + 0.216 × 3 = 2.52 0.24 \times 2 + 0.096 \times 3 + 0.064 \times 3 + 0.24 \times 2 + 0.144 \times 3 + 0.216 \times 3 = 2.52 0.24×2+0.096×3+0.064×3+0.24×2+0.144×3+0.216×3=2.52

输入样例2:
4 3
0.006 0.1 0.2 0.694
输出样例2:
7.3229920752

先想到用暴搜,能够过20%
想到要加上记忆化好像会好一点,下面是记忆化满分代码

#include<bits/stdc++.h>
using namespace std;const int N = 20;
const int M = 1<<16 +5;
const int K = 100;
float A[N];
float state[M][K];
int  n,k;
float eps = 1e-5;int get(int num)
{int cnt = 0;while(num){num &= (num - 1);cnt ++;}return n - cnt;
}float dfs(int res  = 0, int n_coin = 0 , int cnt = 0)
{// 需要状态压缩,不能直接传数组(2^16可以存下)if(state[res][n_coin]) return state[res][n_coin];if(get(res) * k <= n_coin )  return  cnt;//cout<<p<<' ' <<get(res)<< " " << n_coin << ' '<<cnt <<endl; float temp = 0.0;for (int i = 1; i <= n; i ++ ){int j = 1<<i;if(res & j) temp +=A[i] * dfs(res , n_coin + 1 ,cnt + 1); // ?为什么A[i]移出去就对了else temp +=A[i] *dfs( res|j , n_coin , cnt + 1);}return state[res][n_coin] = temp;
}int main()
{scanf("%d%d", &n, &k);for (int i = 1; i <= n; i ++ ){scanf("%f", &A[i]);}printf("%.10f" , dfs());return 0;
}

在这里插入图片描述

但是我最开始的时候写的是下面的代码,只能过30%,代码只dfs里面传递的参数不同,不知道为什么错了,有知道的小伙伴,可以在评论区留言

#include<bits/stdc++.h>
using namespace std;const int N = 20;
const int M = 1<<16 +5;
const int K = 100;
float A[N];
float state[M][K];
int  n,k;
float eps = 1e-5;int get(int num)
{int cnt = 0;while(num){num &= (num - 1);cnt ++;}return n - cnt;
}float dfs(float p  = 1.0,int res  = 0, int n_coin = 0 , int cnt = 0)
{// 需要状态压缩,不能直接传数组(2^16可以存下)float temp = 0;for (int i = 1; i <= n; i ++ ){if(state[res][n_coin]){return state[res][n_coin];}if(get(res) * k <= n_coin ) {return state[res][n_coin] = p * cnt;}int j = 1<<i;if(res & j) temp += dfs(p * A[i] ,res , n_coin + 1 ,cnt + 1);else temp +=dfs(p * A[i] , res + j , n_coin , cnt + 1);}return state[res][n_coin] = temp;
}int main()
{scanf("%d%d", &n, &k);for (int i = 1; i <= n; i ++ ){scanf("%f", &A[i]);}printf("%.10f" , dfs());return 0;
}

在这里插入图片描述
我明白了,见上图(样例里的),存在在结束的时候,状态和硬币数量相同但是概率不同的情况,所以不传递概率更好。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/474393.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

15-大模型 RAG 经验篇

一、LLMs 已经具备了较强能力了&#xff0c;存在哪些不足点? 在 LLM 已经具备了较强能力的基础上&#xff0c;仍然存在以下问题&#xff1a; 幻觉问题&#xff1a;LLM 文本生成的底层原理是基于概率的 token by token 的形式&#xff0c;因此会不可避免地产生"一本正经…

【网络云计算】2024第48周-技能大赛-初赛篇

文章目录 1、比赛前提2、比赛题目2.1、 修改CentOS Stream系统的主机名称&#xff0c;写出至少3种方式&#xff0c;并截图带时间戳和姓名&#xff0c;精确到秒&#xff0c;否则零分2.2、 创建一个名为你的名字的拼音的缩写的新用户并设置密码&#xff0c;将用户名添加到 develo…

C#编写的日志记录组件 - 开源研究系列文章

以前编写过一个日志记录组件的博文&#xff0c;这次发布一个修改过的完善版本。 1、 项目目录&#xff1b; 2、 源码介绍&#xff1b; 1) 实现&#xff1b; 2) 使用&#xff1b; 后面的参数为级别设置&#xff0c;只有大于这个级别的才进行日志记录&#xff0c;限制了日志记录的…

Qt桌面应用开发 第五天(常用控件)

目录 1.QPushButton和ToolButton 1.1QPushButton 1.2ToolButton 2.RadioButton和CheckBox 2.1RadioButton单选按钮 2.2CheckBox多选按钮 3.ListWidget 4.TreeWidget控件 5.TableWidget控件 6.Containers控件 6.1QScrollArea 6.2QToolBox 6.3QTabWidget 6.4QStacke…

css数据不固定情况下,循环加不同背景颜色

<template><div><p v-for"(item, index) in items" :key"index" :class"getBackgroundClass(index)">{{ item }}</p></div> </template><script> export default {data() {return {items: [学不会1, …

【计算机网络安全】湖北大学-mysql事务隔离性实验

参考数据库实验&#xff1a;并发控制实验&#xff08;MySQL&#xff09;-CSDN博客&#xff0c;大佬写的很好 目录 实验环境 事务的隔离级别 1. 读未提交 2. 读已提交 3. 可重复读 4. 序列化 三种要解决的并发问题 1. 脏读&#xff08;Dirty Read&#xff09; 2. 不可重…

版本控制【Git Bash】【Gitee】

目录 一、什么是版本控制&#xff1f; 二、版本控制的种类&#xff1a; 1、本地版本控制 2、集中版本控制 3、分布式版本控制 三、下载Git Bash 四、Git Bash 配置 五、Git Bash使用 1、切换目录&#xff1a;cd 2.查看当前文件路径&#xff1a;pwd 3.列出当前目录下文件…

Qt中实现旋转动画效果

使用QPropertyAnimation类绑定对应的属性后 就可以给这个属性设置对应的动画 //比如自定义了属性 Q_PROPERTY(int rotation READ rotation WRITE setRotation)//给这个属性加动画效果 //参数1&#xff1a;谁要加动画效果 //参数2&#xff1a;哪个属性加动画效果 //参数3&…

Docker 基础命令介绍和常见报错解决

介绍一些 docker 可能用到的基础命令&#xff0c;并解决三个常见报错&#xff1a; 权限被拒绝&#xff08;Permission Denied&#xff09;无法连接到 Docker 仓库&#xff08;Timeout Exceeded&#xff09;磁盘空间不足&#xff08;No Space Left on Device&#xff09; 命令以…

web——upload-labs——第十关——.空格.绕过

审计源码 这次先删除文件名左右的空格&#xff0c;然后又删除了我们文件末尾的.&#xff0c;其次将我们上传的文件名转换为小写&#xff0c;删除文件末尾的::$DATA&#xff0c;最后又删除了文件名左右两侧的空格 根据他的逻辑&#xff0c;我们可以构造文件名phpinfo.php. .就是…

Python | Leetcode Python题解之第564题数组嵌套

题目&#xff1a; 题解&#xff1a; class Solution:def arrayNesting(self, nums: List[int]) -> int:ans, n 0, len(nums)for i in range(n):cnt 0while nums[i] < n:num nums[i]nums[i] ni numcnt 1ans max(ans, cnt)return ans

Stable Diffusion核心网络结构——CLIP Text Encoder

&#x1f33a;系列文章推荐&#x1f33a; 扩散模型系列文章正在持续的更新&#xff0c;更新节奏如下&#xff0c;先更新SD模型讲解&#xff0c;再更新相关的微调方法文章&#xff0c;敬请期待&#xff01;&#xff01;&#xff01;&#xff08;本文及其之前的文章均已更新&…

如何在项目中用elementui实现分页器功能

1.在结构部分复制官网代码&#xff1a; <template> 标签: 这是 Vue 模板的根标签&#xff0c;包含所有的 HTML 元素和 Vue 组件。 <div> 标签: 这是一个普通的 HTML 元素&#xff0c;包裹了 el-pagination 组件。它没有特别的意义&#xff0c;只是为了确保 el-pagi…

海量数据面试题

目录 前言 什么是海量数据 一、利用位图解决 二、利用布隆过滤器解决 三、利用哈希切割解决 前言 在大数据时代&#xff0c;海量数据处理已成为技术领域中的一项重要课题。无论是企业级应用、互联网平台&#xff0c;还是人工智能和机器学习的实现&#xff0c;都离不开对大规…

Diff 算法的误判

起源&#xff1a; 设想一下&#xff0c;假如你桌面上的文件都没有文件名&#xff0c;取而代之的是&#xff0c;你使用通过文件的位置顺序即index来区分它们———第一个文件&#xff0c;第二个文件&#xff0c;以此类推。也许这种方式可行&#xff0c;可是一旦你删除了其中的一…

基于Java Springboot幼儿园管理系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

Misc_01转二维码(不是二进制)

例题ctfhub/隐写v2.0 打开是一张图片 文件分离得到zip&#xff0c;爆破密码得到7878 打开得到0和1&#xff0c; !!!不是二进制转图片&#xff0c;直接是二维码 缩小能看到 000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000…

5.4.2-1 编写Java程序在HDFS上创建文件

本次实战涉及使用Java操作Hadoop HDFS&#xff0c;包括创建文件、判断文件存在性及异常处理。通过手动添加依赖、启动HDFS服务&#xff0c;成功在HDFS上创建和检查文件。进一步探索了文件操作的最佳实践&#xff0c;如检查文件存在性以避免重复创建&#xff0c;以及处理HDFS安全…

MySQL时间字段TIMESTAMP和DATETIME

SELECT global.time_zone, session.time_zone;查询数据库的全局时区和当前会话的时区信息&#xff0c;一般如果使用navicat进行连接&#xff0c;没有显示指定时区信息&#xff0c;会默认使用system_time_zone。 可以使用 SET time_zone 08:00; SELECT global.time_zone, sess…

Android集成FCM(Firebace Cloud Messaging )

集成FCM官方文档 Firebace主页面 将 Firebase 添加到您的 Android 应用 1、进入Firebace页面&#xff0c;创建自己的项目 2、点击自己创建好的项目&#xff0c;在右侧选择Cloud Messaging 3、点击Android去创建 google-services.json 4、将下载的 google-services.json 文件…