原题链接:蓝桥杯历届试题-连号区间数
暴力思路:
首先这个题需要理解这个连续性是什么,比如给你一个数组:1 3 5 4 2,然后我在里面随便去一段(取3 5 4)然后我把它排序(从小到大)发现也是3,4,5 那 就说明是连续的,除此之外当l=r时也算作连续
分别枚举区间的左端点和右端点,对左右端点区间进行sort排序,判断是否连续
暴力做法时间复杂度O(n^3logn)大于O(n^2),所以只能过一部分的数据,但能得一部分得分数
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
using ll=long long;
const int N=5e4+10;
int a[N],bac[N];
int res;
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n;i++)//枚举左右端点i,j,判断是否连续
{
for(int j=i;j<=n;j++)
{
memcpy(bac,a,sizeof a);// 这里要把数组的初始状态存在bac数组中,因为每次sort排序后,数组的顺序会发生改变。
sort(a+i,a+j+1);
bool flag=true;
for(int k=i;k<j;k++)
{
if(a[k+1]-a[k]>1)
{
flag=false;
break;
}
}
if(flag)res++;
memcpy(a,bac,sizeof bac);// 还原数组a的初始状态
}
}
cout<<res;
return 0;
}对暴力做法进行优化,我们假设区间[a,b],则在区间[a,b]之间一共有b-a+1个数,由此说明在区间[a,b]中的
最大值和最小值之间就相差了b-a。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
// 定义常量N为5e4+10(50010),作为数组大小的上限。定义常量INF为1e8(100000000),用作无穷大的值。
const int N = 5e4 + 10, INF = 1e8;
int a[N], bac[N]; // 定义数组a用来存储输入的序列,bac数组定义了但未在代码中使用
int res; // 定义变量res用来统计满足条件的子序列数量
int main() {
// 加速输入输出。禁用C与C++的同步以及手动绑定cin与cout
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n; // 定义n用来接收序列的长度
cin >> n; // 输入序列的长度n
for (int i = 1; i <= n; i++) {
cin >> a[i]; // 循环接收序列的每个值
}
// 双重循环检查所有的(i, j)对,其中i为子序列的起始位置,j为子序列的结束位置
for (int i = 1; i <= n; i++) {
int maxb = -INF, mina = INF; // 初始化当前子序列的最大值和最小值
for (int j = i; j <= n; j++) {
maxb = max(maxb, a[j]); // 更新当前子序列的最大值
mina = min(mina, a[j]); // 更新当前子序列的最小值
// 如果当前子序列的最大值与最小值之差等于子序列的长度差,则找到了一个符合条件的子序列
if (maxb - mina == j - i) res++;
}
}
cout << res; // 输出满足条件的子序列总数
return 0;
}0.0分
1 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复