A - Planets Link
题意:给你N个物品,每个物品类型是a[i],消除任意一个物品的代价为1,消除一个类型的物品代价为C,问消除全部物品的最小代价
数据范围:
思路:贪心,当某个类型的物品数量大于等于C时,使用C代价消除,否则使用该类型物品数量为代价消除
Code:
void solve() {
int n, c;
cin >> n >> c;
vector<int> a(101);
for(int i = 0; i < n; i ++ ) {
int x;
cin >> x;
a[x] ++;
}
int ans = 0;
for(int i = 0; i <= 100; i ++ ) {
if(a[i] > c) {
ans += c;
}else {
ans += a[i];
}
}
cout << ans << endl;
}
B - Meeting on the Line Link
题意:有N个人住在坐标线上,每个人的位置为,每个人有准备时间
,现在你需要找出一个点
,使得
的最大值最小
数据范围:
思路:三分,在
处取得函数最小值,向
两边走会导致函数值增大,还有二分和贪心的做法
Code:
int x[maxn], t[maxn], n;
double check(double c) {
double ans = 0;
for(int i = 0; i < n; i ++ ) {
ans = max(ans, abs(c - x[i]) + (double)t[i]);
}
return ans;
}
void solve() {
cin >> n;
for(int i = 0; i < n; i ++ ) {
cin >> x[i];
}
for(int i = 0; i < n; i ++ ) {
cin >> t[i];
}
double L = 0, R = 2e8;
while(abs(R - L) > 1e-6) {
double mid1 = L + (R - L) / 3;
double mid2 = R - (R - L) / 3;
double check1 = check(mid1);
double check2 = check(mid2);
if(check1 <= check2) {
R = mid2;
}else {
L = mid1;
}
}
cout << L << endl;
}
C - Minimum Notation Link
题意:给你一个字符串,保证
,你有一个操作,你可以选择一个下标
,删除
并在任意一个位置插入
,找到可以达到的最小字典序
数据范围:
思路:贪心,我们将字符和下标存为一个pair对,并对字符排序后,我们会发现我们需要保留的就是从第一个元素的下标开始递增的下标上的字符,剩下的加一和9取min,再排序一次直接输出即可
Code:
void solve() {
vector<pair<char, int>> ve;
string s;
cin >> s;
int n = s.size();
for(int i = 0; i < n; i ++ ) {
ve.pb({s[i], i});
}
sort(all(ve));
int now = -1;
for(int i = 0; i < n; i ++ ) {
if(ve[i].se > now) {
now = ve[i].se;
}else {
ve[i].fi = (char)min(ve[i].fi + 1, (signed)'9');
}
}
sort(all(ve));
for(int i = 0; i < n; i ++ ) {
cout << ve[i].fi;
}
cout << endl;
}
D - Prefixes and Suffixes Link
题意:给你两个长度为的字符串
,你拥有一个操作:
选择一个整数 ,选中
中长度为
的前缀,选中
中长度为
的后缀,交换
问:能否通过任意次操作(可能为0次)使得 ?
数据范围:
思路:我们手摸这个操作,会发现这个操作实质上就是选择 和
两个字符进行交换(0-index):
那么这个操作就绑定了字符 和
,他们只能互相交换,不能和其他对交换,这样的话必须保证相同无序对(
,
)的数量是偶数;如果是奇数并且
不等于
,是无论如何也不可能让
相等的;如果是奇数且有
等于
,我们记录一下这样的对的数量,如果大于1也是不行的,如果等于1,我们可以让这一个独立的对放在正中间即可。
Code:
void solve() {
int n;
cin >> n;
string s1, s2;
cin >> s1 >> s2;
map<pair<char, char>, int> mp;
for(int i = 0; i < n; i ++ ) {
mp[minmax(s1[i], s2[n - i - 1])] += 1;
}
int f = 1, t = 0;
for(auto [x, y] : mp) {
if(y & 1) {
t += 1;
if(x.fi != x.se) {
f = 0;
break;
}
}
}
if(t > 1) f = 0;
yon(f);
}
第一次写题解,如有问题请在评论区告知我