历届试题 连号区间数 (并查集)

/* 历届试题 连号区间数  
时间限制:1.0s   内存限制:256.0MB
      
问题描述
小明这些天一直在思考这样一个奇怪而有趣的问题:

在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*/

//60分,运行超时版
 

import java.util.Arrays;

import java.util.Scanner;

public class Main {
    public static int n;
    public static int sum;
    public static int a[];
    public static void main(String[] args) {
        Scanner sca = new Scanner(System.in);
        
        n = sca.nextInt();
        a = new int[n];
         
        for(int i = 0 ;i < n;i ++) {
            a[i] = sca.nextInt();
        }
        
        int t = 0;
        for(int l = 0; l < n;l ++) {
            for(int r = l;r < n ; r ++) {
                t = r - l + 1;
                int tas = 0;
                int ta[] = new int[t];
                
                for(int k = l ;k <= r ; k ++) {                    
                    ta[tas] = a[k];
                    tas ++;
                }
                
                Arrays.sort(ta);
                 
                if(ta[t-1] - ta[0] == t - 1) {
                    sum ++;
                }
            }
        }
        
        System.out.println(sum);
    }

}

以上算法中每次都生成一个缓冲数组来存放各种存在可能的情况,再者又分别对其排序判断。会使用非常多的时间导致超时。

 

在特殊情况下,可以保存其最大最小值进行判断这个区间是否为全排列。(其实我们在使用sort排序时就也仅仅是赵处它的最小最大值)。所以说,在没有必要的情况下时不要使用太多次sort排序,否则会很容超时。

 更改后正确答案为:

import java.util.Scanner;

public class Main {
    public static int n;
    public static int sum;
    public static int a[];
	public static void main(String[] args) {
		Scanner sca = new Scanner(System.in);
		int max =0 ,min = 50001;
		n = sca.nextInt();
		a = new int[n];
		 
		for(int i = 0 ;i < n;i ++) {
			a[i] = sca.nextInt();
		}
		
		int t = 0;
        for(int l = 0; l < n;l ++) {
        	max =0;
        	min = 50001;
        	for(int r = l;r < n ; r ++) {
        		        		 
        	        if(a[r] > max) {
        	        	max = a[r];
        	        }
        	        if(a[r] < min) {
        	        	min = a[r];
        	        } 		
        		//Arrays.sort(ta); 超时
        		 
        		if(max - min == r - l) {
        			sum ++;
        		}
        	}
        }
        
        System.out.println(sum);
	}

}

 

你可能感兴趣的:(蓝桥杯,历届试题,第十届蓝桥杯全国软件设计大赛)