AcWing - 蓝桥杯集训每日一题(DAY 1——DAY 5)

news/2025/2/12 21:58:45/

文章目录

  • 一、AcWing 3956. 截断数组(中等)
    • 1. 实现思路
    • 2. 实现代码
  • 二、AcWing 3729. 改变数组元素(中等)
    • 1. 实现思路
    • 2. 实现代码
  • 三、AcWing 1460. 我在哪?(简单)
    • 1. 实现思路
    • 2. 实现代码
  • 四、AcWing 3768. 字符串删减(简单)
    • 1. 实现思路
    • 2. 实现代码
  • 五、AcWing 3777. 砖块(简单)
    • 1. 实现思路
    • 2. 实现代码

一、AcWing 3956. 截断数组(中等)

题目描述

给定一个长度为 nnn 的数组 a1,a2,…,ana_{1},a_{2},…,a_{n}a1,a2,,an
现在,要将该数组从中间截断,得到三个非空子数组。
要求,三个子数组内各元素之和都相等。
请问,共有多少种不同的截断方法?

输入格式

第一行包含整数 nnn
第二行包含 nnn 个整数 a1,a2,…,ana_{1},a_{2},…,a_{n}a1,a2,,an

输出格式

输出一个整数,表示截断方法数量。

数据范围

前六个测试点满足: 1≤n≤101≤n≤101n10
所有测试点满足: 1≤n≤105,−10000≤ai≤100001≤n≤10^{5},−10000≤a_{i}≤100001n10510000ai10000

输入样例 1

4
1 2 3 3

输出样例 1

1

输入样例 2

5
1 2 3 4 5

输出样例 2

0

输入样例 3

2
0 0

输出样例 3

0

具体实现

1. 实现思路

  • 我们有一个长度为 n 的数组,将其分成三段,使三段内的元素都相等,求有多少种截断方法。
  • 首先,我们可以先求解一些总和 s,如果 3 不可以整除总和 s 的话,就一定无解。如果想要有解的话,s 一定是 3 的倍数。因此,我们可以先计算出总和 s 和每一段的总和 s/3。
  • 问题就转变为一共有多少种选法,使得每一段的和都是 s/3。
  • 我们可以先确定后面的点,让前面的总和是 2s/3,再选择前面的点,满足第一段是 s/3。
  • 我们再枚举的过程中,可以使用前缀和,计算出从起始点到每一段的前缀和,判断第一段前缀和是 s/3,第二段前缀和是 2s/3 即可。

2. 实现代码

#include <bits/stdc++.h>
using namespace std;
int n;
int a[100005];
long long res=0,cnt=0;
int main()
{cin>>n;for(int i=1;i<=n;i++){int x=0;cin>>x;a[i]=a[i-1]+x;  //前缀和数组}if(a[n]%3!=0 || n<3){cout<<"0"<<endl;}else{for(int j=2;j<n;j++){if(a[j-1]==a[n]/3){cnt++;}if(a[j]==a[n]/3*2){res+=cnt;}}cout<<res;}return 0;
}

二、AcWing 3729. 改变数组元素(中等)

题目描述

给定一个空数组 VVV 和一个整数数组 a1,a2,…,ana_{1},a_{2},…,a_{n}a1,a2,,an
现在要对数组 VVV 进行 nnn 次操作。
iii 次操作的具体流程如下:

  • 从数组 VVV 尾部插入整数 000
  • 将位于数组 VVV 末尾的 aia_{i}ai 个元素都变为 111(已经是 111 的不予理会)。

注意:

  • aia_{i}ai 可能为 0,即不做任何改变。
  • aia_{i}ai 可能大于目前数组 V 所包含的元素个数,此时视为将数组内所有元素变为 111
    请你输出所有操作完成后的数组 VVV

输入格式

第一行包含整数 TTT,表示共有 TTT 组测试数据。
每组数据第一行包含整数 nnn
第二行包含 nnn 个整数 a1,a2,…,ana_{1},a_{2},…,a_{n}a1,a2,,an

输出格式

每组数据输出一行结果,表示所有操作完成后的数组 VVV,数组内元素之间用空格隔开。

数据范围

1≤T≤200001≤T≤200001T20000
1≤n≤2×1051≤n≤2×10^{5}1n2×105
0≤ai≤n0≤a_{i}≤n0ain
保证一个测试点内所有 nnn 的和不超过 2×1052×10^{5}2×105

输入样例

3
6
0 3 0 0 1 3
10
0 0 0 1 0 5 0 0 0 2
3
0 0 0

输出样例

1 1 0 1 1 1
0 1 1 1 1 1 0 0 1 1
0 0 0

具体实现

1. 实现思路

  • 由于我们每次操作都会加入一个数,在操作 i 次之后,新数组的长度就是 i,然后,再将当前数组的最后面的 ai 个数变成 1。
  • 由于第 i 次数组一共有 i 个,将后 ai 个数变为 1,也就是我们将是 i-ai+1 到 i 的区间内的 ai 个数全部变成 1,也就是这个区间内的数据操作一次。
  • 因此,我们可以开一个新数组与原数组长度相等,用以记录区间内数据操作的个数,因为 V 数组当中的 1 不会发生改变,所以,操作多次和操作一次的效果是相同的。
  • 最后,如果新数组当中的元素大于 0,那么 V 数组中对应的元素就是 1,如果新数组中的元素等于 0,那么 V 数组中对应的元素就是 0。

2. 实现代码

#include <bits/stdc++.h>
using namespace std;
const int N=200010;
int n;
int b[N];
int main()
{int T;cin>>T;while(T--){cin>>n;memset(b,0,(n+1)*4);for(int i=1;i<=n;i++){int x;cin>>x;x=min(x,i); //如果x大于i的话就更新成i,因为此时是将数组内的所有元素变为1 int l=i-x+1,r=i; b[l]++;b[r+1]--;}for(int i=1;i<=n;i++){b[i]+=b[i-1];}for(int i=1;i<=n;i++){cout<<!!b[i]<<" ";}cout<<endl;}return 0;
}

三、AcWing 1460. 我在哪?(简单)

题目描述

农夫约翰出门沿着马路散步,但是他现在发现自己可能迷路了!
沿路有一排共 NNN 个农场。
不幸的是农场并没有编号,这使得约翰难以分辨他在这条路上所处的位置。
然而,每个农场都沿路设有一个彩色的邮箱,所以约翰希望能够通过查看最近的几个邮箱的颜色来唯一确定他所在的位置。
每个邮箱的颜色用 A..ZA..ZA..Z 之间的一个字母来指定,所以沿着道路的 NNN 个邮箱的序列可以用一个长为 NNN 的由字母 A..ZA..ZA..Z 组成的字符串来表示。
某些邮箱可能会有相同的颜色。
约翰想要知道最小的 KKK 的值,使得他查看任意连续 KKK 个邮箱序列,他都可以唯一确定这一序列在道路上的位置。
例如,假设沿路的邮箱序列为 ABCDABC
约翰不能令 K=3K=3K=3,因为如果他看到了 ABC,则沿路有两个这一连续颜色序列可能所在的位置。
最小可行的 KKK 的值为 K=4K=4K=4,因为如果他查看任意连续 444 个邮箱,那么可得到的连续颜色序列可以唯一确定他在道路上的位置。

输入格式

输入的第一行包含 NNN,第二行包含一个由 NNN 个字符组成的字符串,每个字符均在 A..ZA..ZA..Z 之内。

输出格式

输出一行,包含一个整数,为可以解决农夫约翰的问题的最小 KKK 值。

数据范围

1≤N≤1001≤N≤1001N100

输入样例

7
ABCDABC

输出样例

4

具体实现

1. 实现思路

  • 我们要找到一个最小的 K,使得字符串当中从 K 分开不存在两个相同的字符串。
  • 我们可以使用暴力解法,也就是 4 个 for 循环,第一重循环枚举每一个 K,第二重循环枚举第一个子串,第三重循环枚举第二个子串,第四重循环判断两个字串是否相同。

2. 实现代码

#include <bits/stdc++.h>
using namespace std;
int n;
string str;
int main()
{cin >> n >> str;for (int k = 1; k <= n; k ++ ){bool flag = false;for (int i = 0; i + k - 1 < n; i ++ ){for (int j = i + 1; j + k - 1 < n; j ++ ){bool same = true;for (int u = 0; u < k; u ++ )if (str[i + u] != str[j + u]){same = false;break;}if (same){flag = true;break;}}if (flag) break;}if (!flag){cout << k << endl;break;}}return 0;
}

四、AcWing 3768. 字符串删减(简单)

题目描述

给定一个由 nnn 个小写字母构成的字符串。
现在,需要删掉其中的一些字母,使得字符串中不存在连续三个或三个以上的 xxx
请问,最少需要删掉多少个字母?
如果字符串本来就不存在连续的三个或三个以上 xxx,则无需删掉任何字母。

输入格式

第一行包含整数 nnn
第二行包含一个长度为 nnn 的由小写字母构成的字符串。

输出格式

输出最少需要删掉的字母个数。

数据范围

3≤n≤1003≤n≤1003n100

输入样例 1

6
xxxiii

输出样例 1

1

输入样例 2

5
xxoxx

输出样例 2

0

输入样例 3

10
xxxxxxxxxx

输出样例 3

8

具体实现

1. 实现思路

  • 我们利用 cnt 存储当前连续出现字符 x 的个数。
  • 若出现了一个字符 x,则 cnt 加一。
  • 若出现了一个其它字符,则 cnt 清零。
  • 若当前 cnt=3,说明遇到了连续三个 x,此时需要删除一次。特别地,此时删除最后一个字符 x 后,可能补位的字符仍为 x,如输入样例 3 所示。此时不能将 cnt 清零,而应该减一,然后继续遍历。

2. 实现代码

#include <bits/stdc++.h>
using namespace std;int main()
{int n;string s;cin>>n>>s;int res=0,cnt=0;for(int i=0;i<n;i++){if(s[i]=='x'){cnt++;if(cnt==3){cnt--;res++;}}else{cnt=0;}}cout<<res<<endl;return 0;
}

五、AcWing 3777. 砖块(简单)

题目描述

nnn 个砖块排成一排,从左到右编号依次为 1∼n1∼n1n
每个砖块要么是黑色的,要么是白色的。
现在你可以进行以下操作若干次(可以是 000 次):
选择两个相邻的砖块,反转它们的颜色。(黑变白,白变黑)
你的目标是通过不超过 3n3n3n 次操作,将所有砖块的颜色变得一致。

输入格式

第一行包含整数 TTT,表示共有 TTT 组测试数据。
每组数据第一行包含一个整数 nnn
第二行包含一个长度为 nnn 的字符串 sss。其中的每个字符都是 WB,如果第 iii 个字符是 W,则表示第 iii 号砖块是白色的,如果第 iii 个字符是 B,则表示第 iii 个砖块是黑色的。

输出格式

每组数据,如果无解则输出一行 −1−11
否则,首先输出一行 kkk,表示需要的操作次数。
如果 k>0k>0k>0,则还需再输出一行 kkk 个整数,p1,p2,…,pkp_{1},p_{2},…,p_{k}p1,p2,,pk。其中 pip_{i}pi 表示第 iii 次操作,选中的砖块为 pip_{i}pipi+1p_{i+1}pi+1 号砖块。
如果方案不唯一,则输出任意合理方案即可。

数据范围

1≤T≤101≤T≤101T10
2≤n≤2002≤n≤2002n200

输入样例

4
8
BWWWWWWB
4
BWBB
5
WWWWW
3
BWB

输出样例

3
6 2 4
-1
0
2
2 1

具体实现

1. 实现思路

  • 并没有要求操作次数最少,因此,只需输出任意一组可成功操作的次数即可。最终的结果只有两种,要么全黑,要么全白, 两种情况可以依次枚举(任一情况都可)。
  • 同一个位置我们最多操作 1 次,因为操作两次的话就变回原样。并且,操作的顺序不影响最后的结果。
  • 其中,第一个砖块只能操作一次,所以,如果第一个砖块跟我们目标颜色相同的话,就不需要进行操作,如果不同的话,就一定会进行操作。第一个砖块是否操作是已经确定的了,第二个砖块也是同样的道理,后续皆同。因此在最后,如果最后一个砖块和目标颜色相同的话,就一定有解,如果不同的话就一定无解,这中间我们只需要操作 n-1 次。

2. 实现代码

#include <bits/stdc++.h>
using namespace std;
int n;
string str;
void update(char &c)
{if(c=='W'){c='B';}else{c='W';}
}
bool check(char c)
{vector<int>res;string s=str;for(int i=0;i<n-1;i++){if(s[i]!=c){update(s[i]);update(s[i+1]);res.push_back(i+1); //字符串从0开始,题目中从1开始}}if(s.back()!=c){return false;}cout<<res.size()<<endl;for(int x=0;x<res.size();x++){cout<<res[x]<<' ';}if(res.size()!=0){cout<<endl;}return true;
}
int main()
{int T;cin>>T;while(T--){cin>>n>>str;if(!check('B')&&!check('W')){cout<<"-1"<<endl;}}return 0;
}

http://www.ppmy.cn/news/30705.html

相关文章

python实现半色调技术图像转换

半色调技术 半色调技术是一种将灰度图像转换为黑白图像的技术。它是通过将灰度图像的像素值映射到黑白像素值上来实现的。 比如说&#xff0c;在一块只能显示纯黑或纯白的屏幕上&#xff0c;如何将一张灰度图显示出灰度的效果&#xff0c;这时就可以用半色调技术实现。 如下…

华为机试题:HJ103 Redraiment的走法(python)

文章目录&#xff08;1&#xff09;题目描述&#xff08;2&#xff09;Python3实现&#xff08;3&#xff09;知识点详解1、input()&#xff1a;获取控制台&#xff08;任意形式&#xff09;的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方…

Go语言结构体,这一篇就够了

Go语言结构体&#xff0c;这一篇就够了1.结构体的概念2.结构体的定义3.结构体的实例化4.结构体初始化5.构造函数6.方法和接收者方法接收者7.嵌套结构体8.结构体的“继承”9.结构体与JSON序列化10.结构体标签&#xff08;Tag&#xff09;Go语言中没有“类”的概念&#xff0c;也…

JavaScript 高级4 :正则表达式

JavaScript 高级4 &#xff1a;正则表达式 Date: January 19, 2023 Text: 正则表达式、正则表达式特殊字符、正则表达式中的替换 目标&#xff1a; 能够说出正则表达式的作用 能够写出简单的正则表达式 能够使用正则表达式对表单进行验证 能够使用正则表达式替换内容 正则…

[项目] Boost搜索引擎

目录 1.项目相关背景 2.项目宏观原理 3.技术栈和项目环境 4.正排索引&&倒排索引 5.去标签与数据清洗 6.构建索引模块Index 6.1正排索引 6.2 建立倒排 jiebacpp使用 建立分词 7.搜索引擎模块Searcher Jsoncpp -- 通过jsoncpp进行序列化和反序列化 处理Cont…

udk开发-稀里糊涂

一、EDK2简介 1.EDK2工作流 ​ 二、EDK2 Packages 1.Packages介绍 ​ EDK2 Packages是一个容器&#xff0c;其中包含一组模块及模块的相关定义。每个Package是一个EDK2单元。 整个Project的源代码可以被分割成不同的Pkg。这样的设计不仅可以降低耦合性&#xff0c;还有利于分…

new set数组对象去重失败

我们知道Set是JS的一个种新的数据结构&#xff0c;和数组类似&#xff0c;和数组不同的是它可以去重&#xff0c;比如存入两个1或两个"123"&#xff0c;只有1条数据会存入成功&#xff0c;但有个特殊情况&#xff0c;如果添加到set的值是引用类型&#xff0c;比如数组…

Validator校验之ValidatorUtils

注意&#xff1a;hibernate-validator 与 持久层框架 hibernate 没有什么关系&#xff0c;hibernate-validator 是 hibernate 组织下的一个开源项目 。 hibernate-validator 是 JSR 380&#xff08;Bean Validation 2.0&#xff09;、JSR 303&#xff08;Bean Validation 1.0&…