题目链接
思路:首先可以想到肯定是先匹配对子答案要大,然后如果匹配到i,匹配对子剩下一张牌,看i+1是否是奇数张牌,如果是,就直接匹配i,i+1,i+2为顺子,就算i+2是偶数张牌,也只是拿这个顺子换一个对子,但i+2剩下的一张牌可能和接下来的牌匹配成顺子,case 4就说明了这一点。
/*首先有对子先凑对子,对子划算。
但是如果当前的数是连续三个数的末尾那个数
那么凑成顺子,比如123345,你把3凑成顺子123后,3还可能和后面组成顺子
如果你凑对子,那么后面顺子的机会就没了*/
#include<iostream>
#include<cstring>
#define maxn 1000000
using namespace std;
int a[maxn];
int main(){
int n,m,x;
while(cin>>n){
memset(a,0,sizeof(a));
for(int i=0;i<n;i++){
cin>>x;
a[x]++;
}
int ans=0;
for(int i=1;i<=maxn;i++){
if(a[i]>=2){
ans+=a[i]/2;
a[i]=a[i]%2;
}
//当前a[i]要么是1个要么0个
if(a[i]<=maxn-2){
if(a[i]==1 &&a[i+1]%2!=0 &&a[i+2]){
ans++;
a[i]--;a[i+1]--;a[i+2]--;
}
}
}
cout<<ans<<endl;
}
return 0;
}
下面是WA的代码
#include<cstring>
#define maxn 100010
using namespace std;
typedef long long ll;
ll n,x,ans;
ll a[maxn];
int main(){
while(cin>>n){
memset(a,0,sizeof(a));
ans=0;
for(int i=1;i<=n;i++){
scanf("%lld",&x);
a[x]++;
}
/*首先有对子先凑对子,对子划算。
但是如果当前的数是连续三个数的末尾那个数
那么凑成顺子,比如123345,你把3凑成顺子123后,3还可能和后面组成顺子
如果你凑对子,那么后面顺子的机会就没了*/
for(int i=1;i<=maxn;i++){
//凑对子
if(a[i]>=2){
ans+=a[i]/2;
a[i]=a[i]%2;
}
//凑顺子
if(i<=maxn-2){
if(a[i+2] &&a[i]==1 &&a[i+1]%2!=0){
ans++;
a[i]--;a[i+1]--;a[i+2]--;
}
}
}
cout<<ans<<endl;
}
return 0;
}