连号区间数

题目描述

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

在 1 ~ NN 的某个全排列中有多少个连号区间呢?

这里所说的连号区间的定义是:

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

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

输入描述

第一行是一个正整数 N(1≤N≤50×104)N(1≤N≤50×104), 表示全排列的规模。

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

输出描述

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

输入输出样例

示例

输入

4
3 2 4 1

输出

7

代码:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    int N;
    scanf("%d", &N); // 读取输入的整数 N,表示数组 num 的长度
    int sum = N; // 初始化 sum 为 N,因为每个单独的数字本身也是一个连号区间
    int num[500000]; // 声明一个整型数组 num,用来存储输入的数字序列,长度最大为 500000
    
    // 依次读取 N 个数字到数组 num 中
    for (int i = 1; i <= N; i++) {
        scanf("%d", &num[i]);
    }
    
    // 外层循环遍历数组 num,以每个元素作为连号区间的起始点
    for (int j = 1; j <= N; j++) {
        int max, min;
        max = min = num[j]; // 初始化 max 和 min 为当前元素 num[j]
        
        // 内层循环从当前元素的下一个位置开始遍历到数组末尾
        for (int x = j + 1; x <= N; x++) {
            if (num[x] > max) // 更新区间内的最大值
                max = num[x];
            if (num[x] < min) // 更新区间内的最小值
                min = num[x];
            
            // 如果当前子数组 num[j] 到 num[x] 是连号区间,则更新 sum
            if ((max - min) == (x - j))
                sum++;
        }
    }
    
    // 输出最终结果 sum,表示所有连号区间的数量
    printf("%d", sum);
    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值