Nike likes playing cards and makes a problem of it.
Now give you n integers, ai(1≤i≤n)
We define two identical numbers (eg: 2,2) a Duizi,
and three consecutive positive integers (eg: 2,3,4) a Shunzi.
Now you want to use these integers to form Shunzi and Duizi as many as possible.
Let s be the total number of the Shunzi and the Duizi you formed.
Try to calculate max(s)
.
Each number can be used only once.
Input
The input contains several test cases.
For each test case, the first line contains one integer n(1≤n≤106
).
Then the next line contains n space-separated integers ai (1≤ai≤n
)
Output
For each test case, output the answer in a line.
Sample Input
7 1 2 3 4 5 6 7 9 1 1 1 2 2 2 3 3 3 6 2 2 3 3 3 3 6 1 2 3 3 4 5
Sample Output
2 4 3 2
Hint
Case 1(1,2,3)(4,5,6)
Case 2(1,2,3)(1,1)(2,2)(3,3)
Case 3(2,2)(3,3)(3,3)
Case 4(1,2,3)(3,4,5)
思路:这题的贪心思想是:我们存下每个牌面有多少张,然后从前到后去判断,当这个牌面有大于等于2张的时候,无论如何先组成对子,因为对子的代价比顺子少1张,然后就开始考虑顺子了,如果当前的牌还剩一张,并且后面一位牌面的牌数为奇数,后面两位的牌面有牌的话,就可以组成一张顺子,有人会想为什么后面两位的牌面有牌的话就直接不管是不是奇数就直接组成顺子了,你可以这样想,因为下一位的牌数为奇数,就说明组成对子后又会剩一张牌,那如果第三位的牌是奇数的,那就正好加上了一张,如果第三位的牌是偶数的,那就没有加上一张当时,因为是只需要1张牌,所以就多出了一张可以与后面组成顺子的牌了。
贴代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
const int maxn = 1000005;
int a,s[maxn];
int n;
int main()
{
while(cin>>n){
memset(s,0,sizeof(s));
for(int i = 0;i < n;i++){
cin>>a;
s[a]++;
}
int ans = 0;
for(int i = 0;i < maxn;i++){
if(s[i] >= 2){
ans += (s[i]/2);
s[i] %= 2;
}
if(s[i]>0 && s[i+1]%2==1 && s[i+2]>0){
ans++;
s[i]--;
s[i+1]--;
s[i+2]--;
}
}
cout<<ans<<endl;
}
return 0;
}