0
点赞
收藏
分享

微信扫一扫

历届试题 连号区间数

问题描述

小明这些天一直在思考这样一个奇怪而有趣的问题:

在1~N的某个全排列中有多少个连号区间呢?这里所说的连号区间的定义是:

如果区间[L, R] 里的所有元素(即此排列的第L个到第R个元素)递增排序后能得到一个长度为R-L+1的“连续”数列,则称这个区间连号区间。

当N很小的时候,小明可以很快地算出答案,但是当N变大的时候,问题就不是那么简单了,现在小明需要你的帮助。

输入格式

第一行是一个正整数N (1 <= N <= 50000), 表示全排列的规模。

第二行是N个不同的数字Pi(1 <= Pi <= N), 表示这N个数字的某一全排列。

输出格式

输出一个整数,表示不同连号区间的数目。

样例输入1 4

3 2 4 1

样例输出1 7 样例输入2 5

3 4 2 5 1

样例输出2 9  版本一:时间复杂度为o(n^3),部分测试用例超时

1 #include<bits/stdc++.h>
2
3 using namespace std;
4 int array[50000];
5 int array1[50000];
6 int Test(int m,int array[])
7 {
8 int flag=1;
9 sort(array,array+m);
10 for(int i=0;i<m-1;i++)
11 {
12 if(array[i]+1!=array[i+1])
13 {
14 flag=0;
15 break;
16 }
17 }
18 return flag;
19 }
20 int main()
21 {
22 int n;
23 cin >> n;
24 memset(array,0,sizeof(array));
25 memset(array1,0,sizeof(array1));
26 for(int i=0;i<n;i++){
27 cin >> array[i];
28 }
29 int sum=n;
30 int step=1;
31 while(true){
32 step++;
33 for(int i=0;i<n-step+1;i++)
34 {
35 for(int j=0;j<step;j++){
36 array1[j]=array[i+j];
37 }
38 int aq=Test(step,array1);
39 if(aq==1) sum++;
40 }
41 if(step==n) break;
42 }
43 cout << sum << endl;
44 return 0;
45 }

版本2 核心思路同版本一,时间复杂度为o(n^2),ac

1 #include<bits/stdc++.h>
2 using namespace std;
3 int array[50000];
4 int main()
5 {
6 int n;
7 int sum=0;
8 cin >> n;
9 memset(array,0,sizeof(array));
10 for(int i=0;i<n;i++){
11 cin >> array[i];
12 }
13 int L;
14 int R;
15 for(int i=0;i<n;i++)
16 {
17 L=array[i];
18 R=array[i];
19 for(int j=i+1;j<n;j++)
20 {
21 if(array[j]>R) R=array[j];
22 if(array[j]<L) L=array[j];
23 if(R-L==j-i) sum++;
24 }
25 }
26 cout << sum+n << endl;
27 return 0;
28 }

 

作者:你的雷哥

本文版权归作者所有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。

举报

相关推荐

0 条评论