码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Global Round 5

时间:2019-10-18 19:18:25      阅读:111      评论:0      收藏:0      [点我收藏+]

标签:tin   tor   签到   ifd   一个   ace   ati   mat   out   

传送门

A. Balanced Rating Changes

签到,分正负搞一下就行。

B. Balanced Tunnel

题意:
给出\(n\)辆车的进洞顺序和出洞顺序,问有多少量车实现了洞中超车。

思路:
对于进洞的车\(i\),找到其出洞之前所有的车,若有车还未进洞,则那辆车实现了超车。
对于出洞序列维护一个指针\(j\),可以证明,任一时刻\(j\)之前的车都处于超车和没超车两种状态,也就是说\(j\)是单调不减的。
然后就类似于双指针搞下就行。


Code

#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
// #define Local
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 5;
 
int n;
 
int a[N], b[N];
bool chk[N], fined[N];
 
void run() {
    for(int i = 1; i <= n; i++) cin >> a[i];
    for(int i = 1; i <= n; i++) cin >> b[i];
    int j = 1;
    for(int i = 1; i <= n; i++) {
        chk[a[i]] = 1;
        while(j <= n && !fined[a[i]] && b[j] != a[i]) {
            if(!chk[b[j]]) fined[b[j]] = 1;
            ++j;
        }
    }
    int ans = 0;
    for(int i = 1; i <= n; i++) {
        ans += fined[i];
    }
    cout << ans << '\n';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
#ifdef Local
    freopen("../input.in", "r", stdin);
    freopen("../output.out", "w", stdout);
#endif
    while(cin >> n) run();
    return 0;
}

C2. Balanced Removals (Harder)

题意:
在三维空间中给出\(n\)个点,现在要不断删除以两个点为对角线顶点的立方体,并要求立方体中不含任何其它点。
输出删除序列。

思路:

  • 可以考虑二维状态怎么处理这个问题。
  • 显然若\(x\)都不同,排序直接删除就行
  • 若存在\(x\)相同,我们需要单独删除横坐标相同的点,最后至多留下一个点,问题转换为上述问题。
  • 那么对于三维状态也同理,只是实现起来稍微复杂一点。

详见代码:


Code

#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
// #define Local
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 50005;
 
int n;
struct Point{
    int x, y, z, id;
    bool operator < (const Point &A) const {
        if(x != A.x) return x < A.x;
        if(y != A.y) return y < A.y;
        if(z != A.z) return z < A.z;
        return id < A.id;
    }
}a[N];
 
void run() {
    for(int i = 1; i <= n; i++) {
        cin >> a[i].x >> a[i].y >> a[i].z;
        a[i].id = i;
    }
    sort(a + 1, a + n + 1);
    std::vector<Point> v2;
    for(int i = 1, j; i <= n; i = j) {
        j = i;
        while(j <= n && a[i].x == a[j].x) ++j;
        std::vector<Point> v;
        for(int k = i, t; k < j; k = t) {
            t = k;
            while(t < j && a[k].y == a[t].y) ++t;
            for(int p = k; p < t; p += 2) {
                if (p + 1 < t) {
                    cout << a[p].id << ' ' << a[p + 1].id << '\n';
                } else {
                    v.push_back(a[p]);
                }
            }
        }
        for(int p = 0; p < sz(v); p += 2) {
            if(p + 1 < sz(v)) {
                cout << v[p].id << ' ' << v[p + 1].id << '\n';
            } else {
                v2.push_back(v[p]);
            }
        }
    }
    for(int i = 0; i < sz(v2); i += 2) {
        cout << v2[i].id << ' ' << v2[i + 1].id << '\n';
    }
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
#ifdef Local
    freopen("../input.in", "r", stdin);
    freopen("../output.out", "w", stdout);
#endif
    while(cin >> n) run();
    return 0;
}

D. Balanced Playlist

题意:
给出一个环,每个点有权值。现在从每个点出发,定义走过路径上点权的最大值为\(max\),那么走到一个点其权值\(v\)满足\(v<\frac{max}{2}\)时停止。
问从每一个点出发所走的路径长度为多少,若无限走下去则输出\(-1\)

思路:
这个题我是暴力*过去的hhhh。
我的做法就是类似于双指针那样,维护两个指针来跑,但复杂度可能高达\(O(n^2)\)。后来我加了点trick就1700ms给卡过去了2333。
但其实\(O(nlogn)\)的做法很多,二分、线段树这些都行...但二分+RMQ应该是最简单的做法吧。
给出我的暴力代码:


Code

#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
// #define Local
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 3e5 + 5;
 
int n;
int a[N];
int ans[N];
//y < x
bool ok(int x, int y) {
    return y < (x + 1) / 2;
}
 
void run() {
    for(int i = 1; i <= n; i++) cin >> a[i];
    for(int i = 1; i <= n; i++) a[i + 2 * n] = a[i + n] = a[i];
    int Min = *min_element(a + 1, a + n + 1);
    int Max = *max_element(a + 1, a + n + 1);
    if(!ok(Max, Min)) {
        for(int i = 1; i <= n; i++) cout << -1 << " \n"[i == n];
        return;
    }
    for(int i = 1, j; i <= n; i = j + 1) {
        j = i;
        int mx = a[i], p = i;
        while(j + 1 <= 3 * n && !ok(mx, a[j + 1])) {
            ++j;
            if(a[j] >= mx) {
                mx = a[j];
                p = j;
            } 
        }
        for(int k = i; k <= p; k++) {
            ans[k] = j + 1 - k;
        }
        while(p < n && ok(a[p + 1], a[j + 1])) {
            ++p;
            ans[p] = j + 1 - p;
        }
        j = p;
    }
    for(int i = 1; i <= n; i++) cout << ans[i] << " \n"[i == n];
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
#ifdef Local
    freopen("../input.in", "r", stdin);
    freopen("../output.out", "w", stdout);
#endif
    while(cin >> n) run();
    return 0;
}

Codeforces Global Round 5

标签:tin   tor   签到   ifd   一个   ace   ati   mat   out   

原文地址:https://www.cnblogs.com/heyuhhh/p/11699927.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!