Codeforces Round #823 (Div. 2) A-C题解
A、Planets
水题。
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define N 10010
#define ll long long
template <class T>
inline void read(T& a){
T x = 0, s = 1;
char c = getchar();
while(!isdigit(c)){ if(c == '-') s = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + (c ^ '0'); c = getchar(); }
a = x * s;
return ;
}
int n, c;
int a[N];
int tong[N];
vector <int> G;
int main(){
// freopen("hh.txt", "r", stdin);
int T; read(T);
while(T--){
G.clear();
memset(tong, 0, sizeof(tong));
read(n), read(c);
for(int i = 1; i <= n; i++)
read(a[i]);
for(int i = 1; i <= n; i++){
if(!tong[a[i]]) G.push_back(a[i]);
tong[a[i]]++;
}
int ans = 0;
for(int i = 0; i < G.size(); i++){ // 对于每一个轨道,看有多少个星球
if(tong[G[i]] > c) ans += c;
else ans += tong[G[i]];
}
cout << ans << endl;
}
return 0;
}
B、Meeting on the Line
十分少见的 B 比 C 难。
两种思路。
第一种,用二分法不断逼近最短时间,并通过时间判断出每个人的可行域。之后得到一总线段交,即为该时间下可以选择的位置区间。受限于精度,当区间足够小时,便可以直接输出区间内任一位置。
第二种,考虑等效转化。如果没有换装时间这个限制,显然我们选择最大和最小值二者的中点即可。但是加上时间限制后,我们考虑将换装时间转化为距离。
可以发现,对于给定的 \(x_0\), 一个人到此处的时间就是其坐标向远端挪时间 \(t_i\) 个单位。因此,可以将一个人拆成两个点。
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define N 1000010
#define ll long long
template <class T>
inline void read(T& a){
T x = 0, s = 1;
char c = getchar();
while(!isdigit(c)){ if(c == '-') s = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + (c ^ '0'); c = getchar(); }
a = x * s;
return ;
}
int a[N];
int t[N];
int main(){
freopen("hh.txt", "r", stdin);
int T; read(T);
while(T--){
int n; read(n);
for(int i = 1; i <= n; i++){
read(a[i]);
}
for(int i = 1; i <= n; i++)
read(t[i]);
set<double> s;
for(int i = 1; i <= n; i++){
s.insert(a[i] - t[i]);
s.insert(a[i] + t[i]);
}
double dis = 0.0;
double minn = *s.begin();
set<double>::iterator it = s.end(); it--;
double maxn = *it;
printf("%.8lf\n", (maxn + minn) / 2.0);
}
return 0;
}
C、Minimum Notation
可以发现,保留当前后缀中的最小数字肯定是最优的。因此,要把最小数字之前的数字全部删掉提到后面来,使其尽量靠前。最后排序输出即可。
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define N 1000010
#define ll long long
template <class T>
inline void read(T& a){
T x = 0, s = 1;
char c = getchar();
while(!isdigit(c)){ if(c == '-') s = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + (c ^ '0'); c = getchar(); }
a = x * s;
return ;
}
char s1[N];
int a[N];
int minn[N];
int main(){
// freopen("hh.txt", "r", stdin);
int T; read(T);
while(T--){
scanf("%s", s1 + 1);
int n = strlen(s1 + 1);
for(int i = 1; i <= n; i++)
a[i] = s1[i] - '0', minn[i] = 1e9;
minn[n+1] = 1e9;
for(int i = n; i; i--){
minn[i] = min(minn[i+1], a[i]);
}
multiset <int> s;
for(int i = 1; i <= n; i++){
if(a[i] > minn[i])s.insert(min(a[i]+1, 9));
else s.insert(a[i]);
}
for(auto it : s){
printf("%d", it);
}
cout << endl;
}
return 0;
}