codeforces 356 C. Compartments 构造 贪心

一辆车,有n个车厢,每个车厢刚好有4个人

车上有n个学生,第i个车厢有a[i]个学生

如果一个车厢里面的学生数 <= 2,这个车厢里的学生会不开心

如果一个车厢里面的学生数 > 2,这个车厢里面的学生会开心

现在学生想和其他人换座位,使得每一位学生都开心

求最小的交换次数

思路:

num[i]表示有num[i]个车厢里面刚好有i个学生

现在,主要的就是处理num[1] 和 num[2]

分情况进行处理就可以了,很简单

代码:

                                            
  //File Name: cf356C.cpp
  //Author: long
  //Mail: 736726758@qq.com
  //Created Time: 2016年07月11日 星期一 20时37分01秒
                                   


#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>

#define LL long long

using namespace std;

const int MAXN = 1000000 + 3;

int num[5];
int a[MAXN];

int solve(int n){
    //for(int i=1;i<=4;i++)
    //    printf("i = %d num[%d] = %d
",i,i,num[i]);
    int ans = 0;
    if(num[1] >= num[2]){
        num[3] += num[2];
        num[1] -= num[2];
        ans += num[2];
        num[2] = 0;
        num[3] += num[1] / 3;
        ans += num[1] / 3 * 2;
        num[1] %= 3;
        if(num[1] <= num[3])
            ans += num[1];
        else if(num[4] && num[1] == 2)
            ans += 2;
        else if(num[4] >= 2 && num[1] == 1)
            ans += 2;
        else 
            ans = -1;
    }
    else{
        num[3] += num[1];
        num[2] -= num[1];
        ans += num[1];
        num[1] = 0;
        num[3] += num[2] / 3 * 2;
        ans += num[2] / 3 * 2;
        num[2] %= 3;
        if(num[2] == 1){
            if(num[4])
                ans++;
            else if(num[3] >= 2)
                ans += 2;
            else
                ans = -1;
        }
        else if(num[2] == 2)
            ans += 2;
    }
    return ans;
}

int main(){
    int n;
    while(~scanf("%d",&n)){
        memset(num,0,sizeof num);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            num[a[i]]++;
        }
        printf("%d
",solve(n));
    }
    return 0;
}
原文地址:https://www.cnblogs.com/-maybe/p/5661581.html