Codeforces Round #823 (Div. 2) A-D
A
题解
知识点:贪心。
对于一个轨道,要么一次性清理,要么一个一个清理。显然,如果行星个数大于直接清理的花费,那么选择直接清理,否则一个一个清理。即 \(\sum \min (c,cnt[i])\),其中 \(cnt[i]\) 表示轨道 \(i\) 的行星个数。
时间复杂度 \(O(n)\)
空间复杂度 \(O(1)\)
代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int cnt[107];
bool solve() {
    int n, c;
    cin >> n >> c;
    memset(cnt, 0, sizeof(cnt));
    for (int i = 1;i <= n;i++) {
        int x;
        cin >> x;
        cnt[x]++;
    }
    int ans = 0;
    for (int i = 1;i <= 100;i++) ans += min(c, cnt[i]);
    cout << ans << '\n';
    return true;
}
int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
        if (!solve()) cout << -1 << '\n';
    }
    return 0;
}
B
题解
方法一
知识点:三分。
按位置从小到大排列,显然约会花费是一个关于 \(x_0\) 的单谷函数,因此可以三分位置。
由于位置最大有 \(10^8\) ,但点的个数只有 \(10^5\) ,考虑先用 map 存储有序对 \((x,t)\) ,其中 \(t\) 是位置 \(x\) 的人最大打扮时间,因为比这个时间少的一定不影响结果。遍历结束以后把 map 内容移到 vector 中用 pair 存储用以三分,check 函数则只要遍历一遍 vector 即可。
时间复杂度 \(O(n \log \max(eps))\)
空间复杂度 \(O(n)\)
方法二
知识点:贪心。
把 \(t\) 等效进位置,如果 \(x_i\) 在 \(x_0\) 左侧,则等效位置是 \(xi - t\) ;如果 \(x_i\) 在 \(x_0\) 右侧,则等效位置是 \(x_i + t\) 。
所有点的左侧等效位置最左的位置,就是等效区间左端点;所有点的右侧等效位置最右的位置就是等效区间的右端点。
如果等效区间的左右端点来自于不同两点的等效点,那么等效区间的中点一定在这两点之间,否则原来的点必有一个能覆盖另一个点,等效区间的左右端点就属于同一个点的等效点。
时间复杂度 \(O(n)\)
空间复杂度 \(O(n)\)
代码
方法一
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int x[100007];
map<int, int> mp;
vector<pair<int, int>> v;
double check(double mid) {
    double mx = 0;
    for (auto [i, j] : v) {
        mx = max(mx, abs(i - mid) + j);
    }
    return mx;
}
bool solve() {
    mp.clear();
    v.clear();
    int n;
    cin >> n;
    for (int i = 1;i <= n;i++) {
        cin >> x[i];
        mp[x[i]] = 0;
    }
    for (int i = 1;i <= n;i++) {
        int T;
        cin >> T;
        mp[x[i]] = max(mp[x[i]], T);
    }
    for (auto [i, j] : mp) {
        v.push_back({ i,j });
    }
    double l = 0, r = v.back().first;
    while (abs(r - l) >= 1e-7) {
        double mid1 = l + (r - l) / 3;
        double mid2 = r - (r - l) / 3;
        if (check(mid1) <= check(mid2)) r = mid2;
        else l = mid1;
    }
    cout << fixed << setprecision(10) << l << '\n';
    return true;
}
int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
        if (!solve()) cout << -1 << '\n';
    }
    return 0;
}
方法二
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int x[100007], T[100007];
bool solve() {
    int n;
    cin >> n;
    int l = 1e9, r = 0;
    for (int i = 1;i <= n;i++) cin >> x[i];
    for (int i = 1;i <= n;i++) cin >> T[i];
    for (int i = 1;i <= n;i++) {
        l = min(x[i] - T[i], l);///最左侧等效点
        r = max(x[i] + T[i], r);///最右侧等效点
    }
    cout << fixed << setprecision(8) << (l + r) / 2.0 << '\n';
    return true;
}
int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
        if (!solve()) cout << -1 << '\n';
    }
    return 0;
}
C
题解
知识点:贪心。
因为要字典序最小,那么一个数字他后面没有更小的数字则可以保留,其他都应该删除,所以从右往左找一个合法的保留序列,其他的数字加一,并且都是位置随意的,于是可以插入到保留下来的序列,并使插入后的序列是从小到大字典序最小的排列。因此直接把保留序列外的数字加一以后,对整个序列排序即可。
也可以直接桶排序。
时间复杂度 \(O(n \log n)\)
空间复杂度 \(O(n)\)
代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
bool solve() {
    string s;
    cin >> s;
    int mi = 10;
    for (int i = s.size() - 1;i >= 0;i--) {
        if (s[i] - '0' <= mi) mi = s[i] - '0';
        else s[i] = min(s[i] + 1, '9' + 0);
    }
    sort(s.begin(), s.end());
    cout << s << '\n';
    return true;
}
int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
        if (!solve()) cout << -1 << '\n';
    }
    return 0;
}
D
题解
知识点:构造。
注意到操作不会改变无序对 \((a_i, b_{ n - i + 1 })\) 数量以及种类。
引理:\(a = b\) ,当且仅当无序对是回文的。
充分性:
当 \(a = b\) 时,如果 \(i\) 处存在一组无序对 \((x, y)\) ,则必然会在 \(n-i+1\) 产生相同一组无序对 \((y, x)\) ,除非当 \(n\) 为奇数时,可以在中间产生一个元素相同的无序对 \((x,x)\) ,因此 \(a = b\) 时,无序对必然成回文状。
必要性:
当无序对是回文的,则第 \(i\) 组无序对 \((x,y)\) 可以对应第 \(n-i+1\) 组无序对 \((y,x)\) ,即 \(a_i = b_i\) ,所以 \(a = b\) 。
充要条件:YES 当且仅当无序对 \((a_i, b_{ n - i + 1 })\) 中元素不同的无序对有偶数个,元素相同的无序对仅在 \(n\) 为奇数时至多 \(1\) 种有奇数个。
充分性:
根据引理,显然满足右边条件。
必要性:
显然没有任何限制时,给出的无序对条件能排列成回文的,现在尝试证明其必然可构造无序对回文。
注意到操作 \(k = i\) 可以使得 \(a[1 \cdots k]\) 和 \(b[k\cdots n]\) 交换位置,即 \((a[k], b[n - k + 1])\) 这一组无序对被置换到了 \(1\) 号位置,同时 \((a[1],b[n])\) 这一组无序对被置换到了 \(i\) 号位置,但这不会改变 \(a[k+1 \cdots n]\) 和 \(b[1\cdots k-1]\) 的顺序,即第 \(k+1\) 到 \(n\) 组无序对及其实际元素顺序没有改变。因此,如果我们想要将无序对通过操作变成一个我们想要的顺序,可以从右往左构造。
假设 \(i+1\) 到 \(n\) 的无序对都安排好了,现在 \(i\) 号位置想要 \(j (j\leq i)\) 号位置的无序对时,可以先 \(k=j\) ,将 \(j\) 号替换到 \(1\) 号,然后 \(k=i\) ,将 \(1\) 号替换 \(i\) 号,过程中 \(i+1 \cdots n\) 的无序对不会改变,包括实际元素顺序。
上述操作最后结果是无序对 \(j\) 替换到 \(i\) ,且 \(j\) 号无序对元素的实际顺序不会改变。但如果我们希望实际元素的顺序也发生改变,我们可以加一个步骤 \(k = 1\) 在中间,即通过 \(k = j, k = 1, k = i\) 替换 \(i\) 号后的 \(j\) 号元素实际顺序与原来是相反的,这也是为什么我们只需要知道无序对顺序即可,因为元素实际顺序是可以随时改变的。
通过上述操作我们可以实现无序对的任意排列,以及无序对实际元素的顺序。因此无序对满足回文条件时,必然可以构造出无序对回文。于是根据引理,得到 \(a = b\) 。
时间复杂度 \(O(n)\)
空间复杂度 \(O(n)\)
代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
string a, b;
int cnt[26][26];
bool solve() {
    memset(cnt, 0, sizeof(cnt));
    int n;
    cin >> n;
    string a, b;
    cin >> a >> b;
    for (int i = 0;i < n;i++) {
        int x = a[i] - 'a', y = b[n - 1 - i] - 'a';
        if (x > y) swap(x, y);
        cnt[x][y]++;
    }
    bool ok = true;
    int esum = 0;
    for (int i = 0;i < 26;i++) {
        for (int j = i;j < 26;j++) {
            if (i == j) esum += cnt[i][j] & 1;
            else ok &= !(cnt[i][j] & 1);
        }
    }
    if (ok && esum <= (n & 1)) cout << "YES" << '\n';
    else cout << "NO" << '\n';
    return true;
}
int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
        if (!solve()) cout << -1 << '\n';
    }
    return 0;
}
												
											Codeforces Round #823 (Div. 2) A-D的更多相关文章
- Codeforces Round #366 (Div. 2) ABC
		
Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...
 - Codeforces Round #354 (Div. 2) ABCD
		
Codeforces Round #354 (Div. 2) Problems # Name A Nicholas and Permutation standard input/out ...
 - Codeforces Round #368 (Div. 2)
		
直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...
 - cf之路,1,Codeforces Round #345 (Div. 2)
		
cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅..... ...
 - Codeforces Round #279 (Div. 2) ABCDE
		
Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name A Team Olympiad standard input/outpu ...
 - Codeforces Round #262 (Div. 2) 1003
		
Codeforces Round #262 (Div. 2) 1003 C. Present time limit per test 2 seconds memory limit per test 2 ...
 - Codeforces Round #262 (Div. 2) 1004
		
Codeforces Round #262 (Div. 2) 1004 D. Little Victor and Set time limit per test 1 second memory lim ...
 - Codeforces Round #371 (Div. 1)
		
A: 题目大意: 在一个multiset中要求支持3种操作: 1.增加一个数 2.删去一个数 3.给出一个01序列,问multiset中有多少这样的数,把它的十进制表示中的奇数改成1,偶数改成0后和给 ...
 - Codeforces Round #268 (Div. 2) ABCD
		
CF469 Codeforces Round #268 (Div. 2) http://codeforces.com/contest/469 开学了,时间少,水题就不写题解了,不水的题也不写这么详细了 ...
 
随机推荐
- 华为交换机设置ntp时间同步
			
操作交换机型号:Huawei S5720 查看时间发现时间不对 [HUAWEI]display clock 2021-04-01 21:41:35 Thursday Time Zone(Default ...
 - zabbix监控添加学习笔记
			
在实际生产环境中,除了CPU.内存等一些系统信息可以挂载zabbix的自带模板Template OS Linux:但是一些公司开发的定制服务需要自己写模板或者监控项去监控: 一.监控公司的java服务 ...
 - 性能浪费的日志案例和使用Lambda优化日志案例
			
有些场景的代码执行后,结果不一定会被使用,从而造成性能浪费.而Lambda表达式是延迟执行的,这正好可以作为解决方案,提升性能 性能浪费的日志案例 日志可以帮助我们快速的定位问题,记录程序运行过程中的 ...
 - HashSet集合的介绍和哈希值
			
java.util.Set接口 extends Collection接口 Set接口的特点: 1.不允许存储重复的元素 2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历 java.uti ...
 - layui框架图片上传至服务器
			
注意:只可用于数据量较小的项目,数据量庞大的项目不要用这个,否则会造成图片数量庞大,至服务器运行速度变慢或瘫痪 HTML代码 //前端使用的是layui框架<div class="la ...
 - Python小游戏——外星人入侵(保姆级教程)第一章 06让飞船移动
			
系列文章目录 第一章:武装飞船 06:让飞船移动 一.驾驶飞船 下面来让玩家能够左右移动飞船.我们将编写代码,在用户按左或右箭头键时做出响应.我们将首先专注于向右移动,再使用同样的原理来控制向左移动. ...
 - Shiro反序列化利用
			
Shiro反序列化利用 前言:hvv单位这个漏洞挺多的,之前没专门研究打法,特有此篇文章. Shiro rememberMe反序列化漏洞(Shiro-550) 漏洞原理 Apache Shiro框架提 ...
 - 五 工厂方法模式【Factory Method Pattern】 来自CBF4LIFE 的设计模式
			
女娲补天的故事大家都听说过吧,今天不说这个,说女娲创造人的故事,可不是"造人"的工作,这个词被现代人滥用了.这个故事是说,女娲在补了天后,下到凡间一看,哇塞,风景太优美了,天空是湛 ...
 - v-if和v-for的优先级是什么?
			
一.作用 v-if 指令用于条件性地渲染一块内容.这块内容只会在指令的表达式返回 true值的时候被渲染 v-for 指令基于一个数组来渲染一个列表.v-for 指令需要使用 item in item ...
 - day33-线程基础03
			
线程基础03 6.用户线程和守护线程 用户线程:也叫工作线程,当线程的任务执行完或者通知方法结束.平时用到的普通线程均是用户线程,当在Java程序中创建一个线程,它就被称为用户线程 守护线程(Daem ...