历届试题 连号区间数
Posted henuliulei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了历届试题 连号区间数相关的知识,希望对你有一定的参考价值。
问题描述
小明这些天一直在思考这样一个奇怪而有趣的问题:
在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
3 2 4 1
样例输出1
7
样例输入2
5
3 4 2 5 1
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 }
以上是关于历届试题 连号区间数的主要内容,如果未能解决你的问题,请参考以下文章