歷屆試題 連號區間數
阿新 • • 發佈:2018-02-13
idt eba spell 數字 bar ans 最大 ive scroll 問題描述
小明這些天一直在思考這樣一個奇怪而有趣的問題:
在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
AC代碼:
小明這些天一直在思考這樣一個奇怪而有趣的問題:
在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
AC代碼:
44 1#include<stdio.h> #include<stdlib.h> #include<stdbool.h> #define N 50000 #define Min(a,b) (a<b)?(a):(b) #define Max(a,b) (a>b)?(a):(b) void input( int * , int ); int spilt( int * , int ); int main(void){ int n , a[N] = {0}; scanf("%d", &n ); input( a , n ); printf("%d\n", spilt( a , n )); return 0; } int spilt( int *a , int n ){ int i , j , Left , Right , sum = 0 ; //Left 最左邊的數 即序列中最小的數 //Right最右邊的數 即序列中最大的數 for( i = 0 ; i < n ; i ++ ){ sum ++ ; //單個數時 即為區間為1的連號區間數 Left = Right = a[i] ; for( j = i+1 ; j < n ; j ++ ){ Left = Min( Left , a[j] ); Right= Max( Right, a[j] ); sum += ( Right-Left == j-i ); //當序列中最大的數減去最小的數 等於序列的長度時 即為連號區間數 } } return sum ; } void input( int *a , int n ){ while( n -- ){ scanf("%d" , a ++ ); } }
2
3
4
5
6
7
8
9void input( int * , int );
10int spilt( int * , int );
11
12int main(void){
13 int n , a[N] = {0};
14 scanf("%d", &n );
15 input( a , n );
16
17 printf("%d\n", spilt( a , n ));
18
19 return 0;
20}
21
22int spilt( int *a , int n ){
23 int i , j , Left , Right , sum = 0 ;
24 //Left 最左邊的數 即序列中最小的數
25 //Right最右邊的數 即序列中最大的數
26 for( i = 0 ; i < n ; i ++ ){
27 sum ++ ;
28 //單個數時 即為區間為1的連號區間數
29 Left = Right = a[i] ;
30 for( j = i+1 ; j < n ; j ++ ){
31 Left = Min( Left , a[j] );
32 Right= Max( Right, a[j] );
33 sum += ( Right-Left == j-i );
34 //當序列中最大的數減去最小的數 等於序列的長度時 即為連號區間數
35 }
36 }
37 return sum ;
38}
39
40void input( int *a , int n ){
41 while( n -- ){
42 scanf("%d" , a ++ );
43 }
44}
歷屆試題 連號區間數