时间限制: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;
}
}