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\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; }