[蓝桥杯] 连号区间数

[蓝桥杯] 连号区间数

峰值内存消耗 < 64M  CPU消耗  < 5000ms

【题目描述 - Problem Description】

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

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

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

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

【输入 - Input】

【输出 - Output】

第一行是一个正整数N (1 <= N <= 50000), 表示全排列的规模。
第二行是N个不同的数字Pi(1 <= Pi <= N), 表示这N个数字的某一全排列。
输出一个整数,表示不同连号区间的数目。

 

【输入样例 1 - Sample Input 1】

【输出样例 1 - Sample Output 1】

4
3 2 4 1
7

【输入样例 2 - Sample Input 2】

【输出样例 2 - Sample Output 2】

5
3 4 2 5 1
9

 

提示 - Hint
第一个用例中,有7个连号区间分别是:[1,1], [1,2], [1,3], [1,4], [2,2], [3,3], [4,4]
第二个用例中,有9个连号区间分别是:[1,1], [1,2], [1,3], [1,4], [1,5], [2,2], [3,3], [4,4], [5,5]

 【题解】

之前自己写了很暴力的判断,蓦然回首,在度娘上看到了更简洁的解法,顿时发觉自己之前代码写的额外判断并没有什么卵用。

一个区间是否连续,就看这个区间中(最大值 - 最小值 + 1)是否等于(区间长度)再之后的判断就没有必要了。

【代码 C++】

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 int data[50005];
 5 int main(){
 6     int n, i, j, maxn, minn, opt;
 7     scanf("%d", &n);
 8     for (opt = i = 0; i < n; ++i) scanf("%d", &data[i]);
 9     for (i = 0; i < n; ++i, ++opt){
10         maxn = minn = data[i];
11         for (j = i + 1; j < n; ++j){
12             maxn = max(data[j], maxn);
13             minn = min(data[j], minn);
14             if (maxn - minn == j - i) ++opt;
15         }
16     }
17     printf("%d", opt);
18     return 0;
19 }

【可测评地址】https://acmore.cc/problem/LOCAL/1600

posted @ 2016-03-21 17:26  Simon_X  阅读(892)  评论(2编辑  收藏  举报