Duizi and Shunzi
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1507 Accepted Submission(s): 627
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.
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 )
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 2HintCase 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)
Source
题意:
给了一些牌,两张牌可以组成一个对子,连续的三张牌能组成一个顺子。每张牌只能使用一次,问最多组成对子和顺子的和为多少。
思路:
可以想到对子优先考虑,然后再考虑成顺子。所以对于第一张牌,有对子成对子,如果对子匹配完了后还剩一张牌就要考虑和后面的牌匹配成顺子。而如果第二张牌是奇数的,那么直接匹配更优因为已经能确定它前面有一张和它匹配了,只需要后面的牌是否匹配。而如果第二张牌是偶数的话,如果匹配,破坏了一次成对机会并且要求第二张以后还要有与第二张匹配的牌。如1,2,2,2,2,3,3这样的情况。所以第二张牌必须也为奇数。而第三张牌的奇偶性没有要求,因为如果第三张牌数为奇数,顺子匹配完了,只剩偶数了,这是我们想要的。如果第三张牌为偶数k,如果不匹配它自己成对会有k/2次,如果匹配顺子加成的对子是(k-1)/2+1仍然是k/2,并且还多提供了一张牌与后面的牌匹配顺子。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int maxn=1000005;
int a[maxn];
int mp[maxn];
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(mp,0,sizeof(mp));
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
mp[a[i]]++;
}
sort(a+1,a+1+n);
int cnt=0;
for(int i=1;i<=n;i++)
{
if(mp[a[i]]>=2)
{
cnt+=mp[a[i]]/2;
mp[a[i]]%=2;
}
if(mp[a[i]]==1&&mp[a[i]+1]%2==1&&mp[a[i]+2]>=1)
{
cnt++;
mp[a[i]]--;
mp[a[i]+1]--;
mp[a[i]+2]--;
}
}
printf("%d\n",cnt);
}
return 0;
}