首页 > 其他分享 >The 2021 ICPC Asia Macau Regional Contest

The 2021 ICPC Asia Macau Regional Contest

时间:2023-10-06 14:33:48浏览次数:40  
标签:return Macau Contest int Regional db fa vector using

A. So I'll Max Out My Constructive Algorithm Skills

首先一行正一行反的把所有的行拼到一起,然后判断一下正着走时候合法不合法就反过来走就好。

#include <bits/stdc++.h>

using namespace std;

#define int long long

using vi = vector<int>;

void solve() {
    int n;
    cin >> n;
    vector<int> a;
    for (int i = 1; i <= n; i++) {
        vi b(n);
        for (auto &j: b) cin >> j;
        if (i & 1) reverse(b.begin(), b.end());
        for (auto j: b) a.push_back(j);
    }
    int x = 0, y = 0;
    for (int i = 1; i < a.size(); i++)
        x += (a[i] > a[i - 1]), y += (a[i] < a[i-1]);
    if( x > y )
        reverse( a.begin(), a.end() );
    for( auto i : a)
        cout << i << " \n"[i == a.back()];
    return ;
}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int TC;
    for (cin >> TC; TC; TC--)
        solve();
    return 0;
}

C. Laser Trap

我们发现,要删除的部分必须是过原点的直线的同一侧。所以我们可以把所有的点按照极角序排序,然后双指针截出 180 度内的所有点即可。

这道题目对精度的要求比较高。所以记得使用acosl(-1)来表示\(\pi\)。

#include <bits/stdc++.h>

using namespace std;

#define int long long

using vi = vector<int>;

using db = long double;

struct Point {
    db x, y;

    Point(db x = 0, db y = 0) : x(x), y(y) {};
};

const db pi = acosl(-1), eps = 1E-18;

bool lt(db a, db b) { return a - b < -eps; }

bool le(db a, db b) { return a - b < eps; }

db theta(Point p) { return atan2(p.y, p.x); }


void solve() {
    int n;
    cin >> n;
    vector<db> a(n + n);
    Point p;
    for (int i = 0; i < n; i++)
        cin >> p.x >> p.y, a[i] = theta(p) + pi, a[i + n] = a[i] + 2.0 * pi;

    sort(a.begin(), a.end(), [](db x, db y) {
        return lt(x, y);
    });
    int res = n;
    for (int l = 0, r = -1; l < n; l++) {
        db t = a[l] + pi;
        while (r + 1 < a.size() and le(a[r + 1], t)) r++;
        res = min(res, r - l );
    }
    cout << res << "\n";
    return;
}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int TC;
    for (cin >> TC; TC; TC--)
        solve();
    return 0;
}

F. Sandpile on Clique

首先如果序列的和大于\(n(n-2)\),则一定无解。对于其他情况,暴力的模拟若干次,如果进行若干次后依旧无解,就可以认为无解。现在考虑每一次分割可以相当于所有数加一,被操作的数减 n。现在考虑这个若干次的阈值是什么?构造的极限情况也不会超过\(2n\)。

#include <bits/stdc++.h>

using namespace std;

#define int long long

using vi = vector<int>;
using pii = pair<int, int>;

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n, cnt = 0;
    cin >> n;
    vector<int> a(n);
    priority_queue<pii> q;
    for (int i = 0; i < n; i++)
        cin >> a[i], q.emplace(a[i], i);
    if (accumulate(a.begin(), a.end(), 0ll) > n * (n - 2)) {
        cout << "Recurrent\n";
        return 0;
    }

    for (int i, x , tt = n * 2 ; tt > 0 and q.top().first + cnt >= n - 1; tt --) {
        i = q.top().second, q.pop();
        x = (a[i] + cnt) / (n - 1), a[i] -= x * n, cnt += x;
        q.emplace(a[i], i);
    }
    if( *max_element(a.begin(), a.end() ) + cnt >= n - 1 ){
        cout << "Recurrent\n";
        return 0;
    }
    for (int i = 0; i < n; i++)
        cout << a[i] + cnt << " \n"[i == n - 1];
    return 0;
}

K. Link-Cut Tree

因为边的缘故,所以前缀所有的边的和也没有后面的一条边的权值打,所以前缀形成的环就是最小环。所有用并查集辅助建图,一旦成环就停止加边,然后把环找出来即可。

#include <bits/stdc++.h>

using namespace std;

#define int long long

using vi = vector<int>;
using pii = pair<int, int>;

struct dsu {
    vi fa;

    dsu(int n = 0) : fa(n + 1, -1) {};

    int getfa(int x) {
        if (fa[x] < 0) return x;
        return fa[x] = getfa(fa[x]);
    }

    bool same(int x, int y) {
        x = getfa(x), y = getfa(y);
        return x == y;
    }

    void merge(int x, int y) {
        x = getfa(x), y = getfa(y);
        if (x == y) return;
        if (fa[x] > fa[y]) swap(x, y);
        fa[x] += fa[y], fa[y] = x;
        return;
    }
};

void solve() {
    int n, m, root = -1;
    cin >> n >> m;
    vector<pii> e(m);
    for (auto &[x, y]: e) cin >> x >> y;
    dsu d(n);
    vector g(n + 1, vector<pii>());
    for (int i = 0; const auto &[x, y]: e) {
        g[x].emplace_back(y, i), g[y].emplace_back(x, i);
        i++;
        if (d.same(x, y)) {
            root = x;
            break;
        }
        d.merge(x, y);
    }
    if (root == -1) {
        cout << "-1\n";
        return;
    }

    vi vis(m + 1), res;
    auto dfs = [g, &vis, & res](auto &&self, int x, int fa, int t) -> void {
        if (!res.empty()) return;
        if (t == 1) {
            for (auto [y, id]: g[x]) {
                if (y == fa) continue;
                if (vis[id] == 2) {
                    for (int i = 0; i < vis.size(); i++)
                        if (vis[i] == 2) res.push_back(i + 1);
                    return;
                }
                vis[id] = 2;
                self(self, y, x, 1);
                vis[id] = 1;
            }
        } else {
            for (auto [y, id]: g[x]) {
                if (y == fa) continue;
                if (vis[id] == 1) {
                    vis[id] = 2;
                    self(self, y, x, 1);
                    vis[id] = 1;
                } else {
                    vis[id] = 1;
                    self(self, y, x, 0);
                    vis[id] = 0;
                }
            }
        }

        return;
    };
    dfs(dfs, root, -1, 0);
    sort(res.begin(), res.end());
    for (auto i: res)
        cout << i << " \n"[i == res.back()];
    return ;
}


int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int TC;
    for (cin >> TC; TC; TC--)
        solve();
    return 0;
}

标签:return,Macau,Contest,int,Regional,db,fa,vector,using
From: https://www.cnblogs.com/PHarr/p/17744553.html

相关文章

  • The 2022 ICPC Asia Jinan Regional Contest
    A.Tower首先用了dp验证出把一个数字变成另一个数字的最优解一定是能除就先进行除法,然后再使用加一减一。这样我们就有\(O(\logn)\)的复杂度求出把一个数变成另一个数的最小代价。然后就是猜测最终的目标一定是某个数除了若干次二得到的。所以就枚举一下目标即可。#include......
  • The 2018 ACM-ICPC Asia Qingdao Regional Contest, Online (The 2nd Universal Cup
    The2018ACM-ICPCAsiaQingdaoRegionalContest,Online(The2ndUniversalCup.Stage1:Qingdao)J-PresstheButton\(1\leqa,b,c,d\leq10^6\)题解容易发现存在循环节,每次位于\(gcd(a,c)\)的倍数的位置所以我们考虑处理一个循环节内的情况如果\(v\le......
  • AtCoder Grand Contest 036 F Square Constraints
    洛谷传送门AtCoder传送门本质是\(p_i\in[l_i,r_i]\)的计数问题。当\(1\lei\len\)时,\(l_i\)才可能不等于\(1\)。考虑容斥,设钦定\(m\)个不满足条件(上界为\(l_i-1\)),其余任意(上界为\(r_i\))。然后按照上界排序后dp,设\(f_{i,j}\)为考虑前\(i\)个元素,已经......
  • 2017 China Collegiate Programming Contest Final (CCPC-Final 2017)
    Preface今天打学校统一要求的这场CCPC2017Final,直接被打爆了,各种数学题搞得人生活不能自理主要是H徐神开场就秒出了正确的思路,然后一心认准高斯消元然后一直想+写+调到结束都没卡过去比赛最后20min的时候祁神想到了更好写的基于施密特正交化的方法,可以碍于时间有限没调出来不......
  • AtCoder Beginner Contest 288 Ex A Nameless Counting Problem
    洛谷传送门AtCoder传送门考虑到规定单调不降比较难搞。先设\(g_t\)为长度为\(t\)的满足条件的序列个数(可重且有顺序)。求这个可以设个dp,\(f_{d,i}\)表示考虑到从高到低第\(d\)位,当前\(t\)个数中有\(i\)个仍然顶上界,并且之前的位都满足异或分别等于\(X\)的限制。......
  • AtCoder Grand Contest 056 D Subset Sum Game
    洛谷传送门AtCoder传送门考虑若\(n\)是奇数怎么做。枚举Alice第一次选的数\(a_i\),然后考虑把剩下的数两两结成一个匹配,若Bob选了其中一个,Alice就选另一个。容易发现排序后奇数位和它右边的偶数位匹配最优。那么设奇数位的和为\(A\),偶数位的和为\(B\),此时Alice获胜......
  • AtCoder Beginner Contest 178 E
    AtCoderBeginnerContest178EE-DistMax曼哈顿距离最大点对\(ans=max(|x_i-x_j|+|y_i-y_j|)\)考虑去绝对值,4种情况。sort一下取max即可。#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintN=2e5+10;intx[N],y[N];intp[4][N];......
  • 2022 China Collegiate Programming Contest (CCPC) Weihai Site
    PrefaceVP到自己学校出的题了可海星,不得不说学长们出的题比起昨天VP的CCPC2022广州做起来要舒服地多这场前面写题都很顺基本都是一发过,中期的medium也没怎么卡思路和卡机子,一道一道地慢慢出最后一个小时徐神RushF可惜没Rush出来,然后我和祁神坐在下面把B的做法给搞出来了,但不知......
  • The 2022 ICPC Asia Shenyang Regional Contest
    C.ClampedSequence因为\(n\)的范围不大,并且可以猜到\(l,r\)中应该至少有一个在\(a_i,a_i-1,a_i+1\)上。所以直接暴力枚举\(l\)或\(r\)然后暴力的计算一下#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongusingvi=vector<int>;int32_tmain(){......
  • AtCoder Beginner Contest 322
    A-FirstABC2解题思路签到Code#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;voidsolve(){ intn; cin>>n; strings; cin>>s; intp=s.find("ABC"); if(p==-1)cout<<p<<'\n&......