HDOJ6188 Duizi and Shunzi(贪心)

题目链接
思路:首先可以想到肯定是先匹配对子答案要大,然后如果匹配到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;
}

猜你喜欢

转载自blog.csdn.net/qq_37360631/article/details/80031508