【CodeForces - 746】Numbers Exchange(思維)

題意:給一個長度爲n的序列,要求將其中一些數字用小於m的數字替換使得這個序列中不出現重複的數字,並且奇數和偶數的個數一樣。

思路:

首先將重複的數字進行轉換,看看原序列是那種數多,假如奇數多,讓重複的奇數轉換成偶數,讓重複的偶數轉換成沒出現過的偶數,用兩個變量表示現在可以選的奇數和偶數是那些,不要超過m。接下來序列沒有重複的數字,然後掃一遍,奇數多,就找奇數轉成偶數,否則找偶數。

ac代碼:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<vector>
#include<unordered_map>
#define mod (1000000007)
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 5;
const int inf = 0x3f3f3f3f;
unordered_map<ll,int> mp;
ll a[maxn];
int main() {
    ll n,m,ne=0,no=0,cg=0,ff=1,num=0;
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]),mp[a[i]]++,no+=a[i]&1,ne+=(1-a[i]&1);
    ll even=2,odd=1,nno,nne;cg=ne-no;
    for(auto it:mp){
        if(it.second>1){
            if(it.first&1) nne+=it.second-1;
            else nno+=it.second-1;
        }
    }
    for(int i=1;i<=n;i++){
        while(mp[even]) even+=2;
        while(mp[odd]) odd+=2;
        if(mp[a[i]]>1){
            num++;
            mp[a[i]]--;
            if (a[i] & 1)
                if (cg < 0) {//奇數多,奇數->偶數
                    a[i] = even;
                    if(even>m)ff=0;
                    mp[even]++;
                    cg+=2;
                } else {//奇數->奇數
                    a[i] = odd;
                    if(odd>m)ff=0;
                    mp[odd]++;
                }
            else if (cg <= 0) {//奇數多,偶數->偶數
                a[i] = even;
                if(even>m)ff=0;
                mp[even]++;
            } else {//偶數->奇數
                a[i] = odd;
                if(odd>m)ff=0;
                mp[odd]++;
                cg-=2;
            }
        }
    }

    if(!ff||n&1) puts("-1");
    else{
        for(int i=1;i<=n;i++){
            while(mp[even]) even+=2;
            while(mp[odd]) odd+=2;
            if(a[i]&1&&cg<0){
                num++;
                a[i]=even;
                if(even>m)ff=0;
                mp[even]++;
                cg+=2;
            }
            else if(a[i]%2==0&&cg>0){
                num++;
                a[i]=odd;
                if(odd>m)ff=0;
                mp[odd]++;
                cg-=2;
            }
        }
        if(ff==0) puts("-1");
        else{
            printf("%d\n",num);
            for(int i=1;i<=n;i++) printf("%lld%c",a[i],i==n?'\n':' ');
        }
            //特殊判斷沒有相同的時候
    }
    return 0 ;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章