Codeforces Round #823 (Div. 2) A-C

A.planets

题意:
就是有很多个东西会在同一个点上,你可以选择花一块钱消灭一个东西,也可以选择花c块钱消灭一个点上的所有东西,问你最少花多少钱可以消灭所有点的东西。
思路:
就看看是花一块钱一个个消灭的钱少,还是c块钱消灭所有的钱少。

#include<iostream>
#include<vector>
#include<cstdio>
#include<bitset>
#include<unordered_map>
#include<cmath>
#include<stack>
#include<algorithm>
#include<queue>
#include<map>
#define int long long
using namespace std;
const int maxn = 1e5 + 5;
int counts[105];
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin >> t;
	while (t--)
	{
		memset(counts, 0, sizeof(counts));
		int n, c;
		cin >> n >> c;
		for (int i = 1; i <= n; i++)
		{
			int num;
			cin >> num;
			counts[num]++;
		}
		int res = 0;
		for (int i = 0; i <= 100; i++)
		{
			res += min(counts[i], c);
		}
		cout << res << endl;
 
	}
	return 0;
}

B.Meeting on the Line
这题是真尼玛抽象……

题意:
给出每个人的位置xi和每个人的穿衣时间ti,让你求一个位置,使得所有人中花费时间最多的这个人,花费的时间最小。

题解:
用二分法,但位置不好二分,不一定具有单调性。所以二分时间。假设二分的这个时间T,是所有人花费时间中的最大值。
那么根据题意就有ti+|xi-x0|<=T,即ti+xi-T<=x0<=T+xi-ti。如果所有人的x0范围有交集,那么选取的这个时间T就是合法的。

#include<iostream>
#include<vector>
#include<cstdio>
#include<bitset>
#include<unordered_map>
#include<cmath>
#include<stack>
#include<algorithm>
#include<queue>
#include<iomanip>
#include<map>
#define int long long
using namespace std;
const int maxn = 1e5 + 5;
int a[maxn], b[maxn];
double ans = 0;
bool check(double mid,int n)
{
	double l = -1e9, r = 1e9;
	for (int i = 1; i <= n; i++)
	{
		if (mid < b[i])
			return false;
		else
		{
			l = max(l, a[i] + b[i] - mid);
			r = min(r, a[i] + mid - b[i]);//求区间交集
		}
	}
	ans = l;
	return r+(1e-8) >= l;//允许的误差
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin >> t;
	while (t--)
	{
		int n;
		cin >> n;
		for (int i = 1; i <= n; i++)
			cin >> a[i];
		for (int i = 1; i <= n; i++)
			cin >> b[i];
		double l = 0, r = 1e9;
		for (int i = 0; i < 100; i++)
		{
			double mid = (l + r) / 2;
			if (check(mid,n))
				r = mid;
			else
				l = mid;
		}
		check(l,n);//需要求出位置
		cout <<std::fixed<<setprecision(7) << ans<< endl;
	}
	return 0;
}

C. Minimum Notation
题意:
给你一串数字,你可以选择让一个数字d变成min(d+1,9),然后让它插在任意一个位置,让你通过这种操作变出一个字典序最小的数字串。
思路:
通过题目所给的操作,不会让数字变小,所以要将原本数字串中,小的放在前面。比如04829,要将2插在0后面,就需要把4和8变成5和9然后随便放在一个位置,所以先不用管5和9,等最后输出答案的时候,在按字典序输出就行了。

#include<iostream>
#include<vector>
#include<cstdio>
#include<bitset>
#include<unordered_map>
#include<cmath>
#include<stack>
#include<algorithm>
#include<queue>
#include<map>
#define int long long
using namespace std;
const int maxn = 1e5 + 5;
int counts[maxn];
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin >> t;
	while (t--)
	{
		queue<int> num[10];
		string s;
		cin >> s;
		for (int i = 0; i < s.length(); i++)
			num[s[i] - '0'].push(i);
		string ans = "";
		string pre = "";
		for (int i = 0; i <= 9; i++)
		{
			while (!num[i].empty())
			{
				int l = num[i].front();
				for (int j = i+1; j <= 9; j++)
				{
					while (!num[j].empty()&&num[j].front() < l)
						pre = pre + (char)(min(j+1,1LL*9) + '0'), num[j].pop();
				}
				ans = ans + (char)(i + '0');
				num[i].pop();
			}
		}
		ans = ans + pre;
		sort(ans.begin(), ans.end());
		cout << ans << endl;
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值