CF1203 兼第五次训练赛(F)

CF 1203 Boxers
题意:
n个拳击手,每个体重都可以减一 加一 或不变,问该怎么操作才能使不同体重拳击手数量最多。
思路:
贪心思想,先记录每个体重有多少人,一个体重最多能扩展成3种体重,所以从小到大开始要先将体重-1看是否已经存在,若存在,则不变,若原体重存在则判断+1是否存在,若都不存在就将该体重进行标记,若是从大到小循环,则是优先级反过来。解释为什么要向一端移动,因为要尽可能给能扩展成两个或三个体重的体重让位置,所以要向递增或递减方向移动。
注意要特判体重为1的选手。
引用如下代码

#include<string.h>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define ll long long
 
ll a[200000];
ll tp[150005];
ll tp2[150005];
 
int main() {
	ll n;
	scanf("%lld",&n);
	//这里是两个桶排,tp 记录的是不同体重选手的数量
	//tp2 记录的是某个体重是否被加入队伍中。
	memset(tp, 0, sizeof(tp));
	memset(tp2, 0, sizeof(tp2));
	
	for(int i = 0; i < n; i++) {
		scanf("%lld",&a[i]);
		tp[a[i]]++;
	}
	for(int i = 1; i < 150001; i++) {
		if(i == 1) {
		//这里特判体重为1的选手
			if(tp[i] != 0) {
				tp2[i]++;
				tp[i]--;
			}
			if(tp[i] != 0) {
				tp2[i+1]++;
				tp[i]--;
			}
		}
		else {
			if(tp[i] != 0) {
				//优先降低体重
				if(tp2[i-1] == 0) {
					tp2[i-1]++;
					tp[i]--;
				}
				//然后保持体重
				if(tp[i] != 0 && tp2[i] == 0) {
					tp[i]--;
					tp2[i]++;
				}
				//最后才是提升体重。
				if(tp[i] != 0 && tp2[i+1] == 0) {
					tp[i]--;
					tp2[i+1]++;
				}
			}
		}
	}
	ll ans = 0;
	for(int i = 0; i < 150005; i++) {
		if(tp2[i] != 0)
			ans++;
	}
	cout << ans << endl;
	
	return 0;
}

Cu1
发布了30 篇原创文章 · 获赞 2 · 访问量 971

猜你喜欢

转载自blog.csdn.net/CUCUC1/article/details/104436627
今日推荐