Codeforces Round #707 (Div. 2)
A.Alexey and Train
题意:
英语杀我
给出 \(a,b,c\) 三个数组分别表示到第 \(i\) 个车站的预期时间,离开时间,以及从\(i-1到 i\) 的额外时间;
从\(i-1到i\)所需的总时间为\(a_i - b_{i-1} + c_i\)
火车从\(i\)站离开有两个限制条件
- 在车站必须停留至少 \(\lceil \cfrac{b_i-a_i}{2} \rceil\) 时间
- 当前时间大于\(b_i\)
sol
模拟就行
\(ans\)每一次加上从\(i-1到i\)所需的时间和 在车站至少停留的时间 ,然后和\(b_i\) 取最大值即可
注意特判最后一站的情况
code
const int maxn = 2e5 + 10;
int n,m;
int a[maxn],b[maxn],c[maxn];
void solve() {
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i] >> b[i];
}
for(int i = 1; i <= n; i++) {
cin >> c[i];
}
int ans = 0;
for(int i = 1; i <= n; i++) {
ans += a[i] - b[i-1] + c[i];
if(i == n) break;
int tmp = (ans + (b[i]-a[i] + 1) / 2);
if(tmp < b[i]) tmp = b[i];
ans = tmp;
}
cout << ans << "\n";
}
B. Napoleon Cake
题意
给一个数组 \(a\) , 第\(i\)个数影响它前面的 \(a[i]-1\) 个位置的数(包括他自己),问最后有那些位置被影响,那些没有被影响
sol
按照题意差分即可
code
void solve() {
cin >> n ;
CLR(b,0);
for(int i = 1; i <= n; i++) {
cin >> a[i];
int l = max(i - a[i] + 1,0) ;
int r = i+1;
b[r]--;
b[l]++;
}
for(int i = 1; i <= n; i++) {
b[i] += b[i-1];
cout << (b[i] ? 1 : 0) << " \n"[i==n];
}
}
C. Going Home
题意
给一个数组 \(a\) ,查看是否有四个数满足 \(a_i+a_j = a_z+a_w\); 有的话需要输出 \(i,j,z,w\)
sol
首先想到就是枚举 \(i,j\) 的 \(O(n^2)\) 算法,但不用想都知道暴力肯定是过不了的(谁会想到\(div2 c\) 给你来个暴力啊,而且当时过题的人也不是很多....)
赛场上的做法是 :
将数组排序后新开一个数组\(c\)记录两两之间的差值,可以发现当出现相同的差值且它们不是连续的时候就可行 比如 \(1,2,5,6\).
但当数组为 \(1,2,3,7,9\) 这样时显然就无法正确判断,发现这些数两两之间相隔并不是一位,所以剩下的数 暴力枚举数之间的差值,然后判断即可
赛后发现看题解暴力也可过,根据抽屉原理,\(a_i+a_j<=5e6\),所以在枚举至多\(5e6\)的数之后,一定会出现一对不同的\(i,j\)有着不同的和,之后尝试了以下,发现经过上面优化之后,速度比纯暴力快几倍
赛时code
struct node{
int w,id;
}a[maxn],d[maxn];
int n,m;
int c[maxn],vis[maxn],b[maxn],id[maxn];
void solve() {
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i].w;
a[i].id = i;
}
sort(a+1,a+1+n,[](node a,node b){
return a.w < b.w;
});
for(int i = 2; i <= n; i++) {
c[i] = (a[i].w - a[i-1].w);
}
for(int i = 2; i <= n; i++) {
if(b[c[i]] == 0) b[c[i]] = i;
else {
if(b[c[i]] < i - 1) {
cout << "YES" << "\n";
int x1 = b[c[i]] - 1;
int x2 = b[c[i]];
cout << a[x1].id << " "<<a[i].id <<" " <<a[x2].id << " " << a[i-1].id << "\n";
return;
}
}
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= i - 1; j++) {
int tmp = a[i].w - a[j].w;
if(d[tmp].w == 0) {
d[tmp].w = j;
d[tmp].id = i;
}
else {
if(d[tmp].id < j) {
int x1 = d[tmp].w;
int x2 = d[tmp].id;
cout << "YES" << "\n";
cout << a[x1].id << " "<<a[i].id <<" " <<a[x2].id << " " << a[j].id << "\n";
return;
}
}
}
}
cout << "NO" << "\n";
}