Duizi and Shunzi
Problem Description
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)
解题思路:
首先需要对牌排个序,然后从前往后遍历牌。
由于顺子需要3张牌而对子需要两张,所以优先选择出顺子。
当考虑牌i的时候,如果牌i-1和i-2都有剩余,那么牌i就可以和他们组成顺子,这样只消耗一张牌i,如果组对子就需要两张。剩下的然后再组成对子。这样就可以保证答案是正确的。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
const int N = 1e6+10;
using namespace std;
typedef long long ll;
ll a[N];
ll cnt[N];
int main()
{
ll n;
while(~scanf("%lld",&n))
{
memset(cnt,0,sizeof(cnt));
for(int i = 0 ; i < n ; i ++)
{
scanf("%lld",&a[i]);
cnt[a[i]] ++;
}
sort(a,a+n);
ll ans = 0;
for(int i = 0 ;i < n ; i ++)
{
if(a[i] <= 2)
{
ans +=cnt[a[i]]/2;
cnt[a[i]] = cnt[a[i]]%2;
}
else if(cnt[a[i]-1] && cnt[a[i]-2] && cnt[a[i]])
{
cnt[a[i]] --;
cnt[a[i]-2] --;
cnt[a[i]-1] --;
ans ++;
}
ans += cnt[a[i]]/2;
cnt[a[i]] = cnt[a[i]]%2;
}
printf("%lld\n",ans);
}
}