hiho#1818 : 顺子组合

时间限制:10000ms

单点时限:1000ms

内存限制:256MB

描述

你有一个包含N个整数的数组:A1, A2, ... AN。我们将3个或3个以上数值连续的整数序列称作顺子,例如[1, 2, 3]、[5, 6, 7, 8]和[10, 11, 12, 13, 14, 15, 16]都是顺子。  

请你判断A数组是否能拆分成若干个顺子的组合。要求每个整数Ai恰好只属于其中一个顺子。

输入

第一行包含一个整数T代表测试数据的组数。  

每组数据第一行包含一个整数N。  

每组数据第二行包含N个整数A1, A2, ... AN。  

1 ≤ T ≤ 10  

1 ≤ N ≤ 10000  

0 ≤ Ai ≤ 100000

输出

对于每组数据输出YES或者NO代表是否能拆分成顺子组合。

样例输入

2  
7  
4 1 3 2 5 4 6  
8  
4 1 3 2 5 4 6 6

样例输出

YES  
NO

分析

利用计数排序的思想,判断数到第N个数的时候是否有断的,若断了或者在所有的数都执行完之后仍有1/2的数组,则不能拆分成顺子。到第N个数的时候,N前面的连续的数组长度可分为1,2,3+,加上第N个数如果不能组成2/3的序列,则不能拆分。

AC代码 JAVA

import java.io.BufferedReader;
import java.io.InputStreamReader;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main{
    public static void main(String[] args) {


        int maxn = 100001;
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        try

        {
            int n = Integer.parseInt(bf.readLine());

            for (int i = 0; i < n; i++) {
                int[] count = new int[maxn];
                int m = Integer.parseInt(bf.readLine());
                String[] s = bf.readLine().split("\\s+");

                for (int j = 0; j < m; j++) {
                    int num = Integer.parseInt(s[j]);
                    count[num]++;
                }

                boolean ans = true;
                int length1 = 0, length2 = 0, length3 = 0;
                for (int k = 0; k < maxn; k++) {
                    if (count[k] >= length1 + length2 + length3) {
                        int tlength1 = length1, tlength2 = length2, tlength3 = length3;
                        length3 = tlength2 + tlength3;
                        length2 = tlength1;
                        length1 = count[k] - tlength1 - tlength2 - tlength3;
                    } else if (count[k] >= length1 + length2) {
                        length3 = count[k] - length1;
                        length2 = length1;
                        length1 = 0;
                    } else {
                        ans = false;
                        break;
                    }
                }
                if (length1 > 0 || length2 > 0) ans = false;
                if (ans) System.out.println("YES");
                else System.out.println("NO");
            }
        } catch (
                Exception e)

        {
            System.out.println(e);
        }
        return;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值