您的位置:首页 > 其它

codeforces 356 C. Compartments 构造 贪心

2016-07-11 20:52 393 查看
一辆车,有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\n",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\n",solve(n));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: