问题描述
小明这些天一直在思考这样一个奇怪而有趣的问题:
在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 }
作者:你的雷哥
本文版权归作者所有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。