AtCoder Beginner Contest 139

AtCoder Beginner Contest 139

https://atcoder.jp/contests/abc139
5/6:今天前4题都很水,e还可以但是比较基础,f是计算几何的一个结论,挺没意思的,还是昨天的f比较好玩

A - Tenki

#include <bits/stdc++.h>

using namespace std;

int main () {
    string s, t;
    cin >> s >> t;
    int ans = 0;
    for (int i = 0; i < 3; i++) {
        if (s[i] == t[i])   ans ++;
    }
    cout << ans;
}

B - Power Socket

#include <bits/stdc++.h>

using namespace std;

int main () {
    int a, b;
    cin >> a >> b;
    cout << (b + a - 3) / (a - 1);
}

C - Lower

#include <bits/stdc++.h>
#define ll long long

using namespace std;
const int N = 1e5 + 5;
int a[N], n;

int main () {
    cin >> n;
    for (int i = 1; i <= n; i++)    cin >> a[i];
    int ans = 1, len = 1;
    for (int i = 2; i <= n; i++) {
        if (a[i] <= a[i-1]) len ++;
        else {
            ans = max (ans, len);
            len = 1;
        }
    }
    ans = max (ans, len);
    cout << ans - 1;
}

//最长连续不增子序列长度-1

D - ModSum

#include <bits/stdc++.h>

using namespace std;

int main () {
    int n;
    cin >> n;
    cout << 1ll * n * (n - 1) / 2;
}

E - League

拓扑排序,注意点的离散化,输出最长链。
其他没啥要注意的了

#include <bits/stdc++.h>
#define ll long long

using namespace std;
const int N = 1005, M = N * N + 2 * N;
int n, a[M], ans, dis[M];
int d[M], top[M], cnt;
int h[M], ne[M], e[M], idx;
set<int> s; //存点

void add (int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

bool topsort() {
    queue<int> q;
    n = s.size ();
    for (int i = 1; i <= n; i++)    a[i] = *s.begin (), s.erase (s.begin ());
    for (int i = 1; i <= n; i++) {
        if (d[a[i]] == 0)    q.push(a[i]);
    }
    while (q.size()) {
        int t = q.front();
        ans = max (ans, dis[t]);
        top[cnt++] = t;
        //cout << t << endl;
        q.pop();
        for (int i = h[t]; i != -1; i = ne[i]) {
            int j = e[i];
            d[j]--; // j 的入度 --
            if (d[j] == 0)    q.push(j);
            dis[j] = dis[t] + 1;
        }    
    }
    if (cnt < n)    return 0;
    else    return 1;
}

int main() {
    memset (h, -1, sizeof h);
    cin >> n;
    for (int i = 1; i <= n; i++) {
        int val = 0;
        for (int j = 1; j < n; j++) {
            int x, y = i;
            cin >> x;
            if (x > y)  swap (x, y);
            int val2 = x * (n + 1) + y;
            s.insert (val2);
            if (j > 1) {
                add (val, val2);
                d[val2] ++;
                //cout << val << ' ' << val2 << endl;
            }
            val = val2;
        }
    }
    if (!topsort ())   cout << "-1\n";
    else    cout << ans + 1 << endl;
}

//非常经典拓扑排序
//答案是拓扑序层级长度(最长链)
//点为安排关系
//点是离散的

F - Engines

计算几何。
极角排序结论:将多个向量向加时,最优的情况是所有边的极坐标单调。

#include <bits/stdc++.h>

using namespace std;
const int N = 205;
typedef pair<int, int> pii;
pii p[N];
int n;

bool cmp (pii x, pii y) {
    return atan2 (x.second, x.first) < atan2 (y.second, y.first);
}

int main () {
    cin >> n;
    for (int i = 1; i <= n; i++)    cin >> p[i].first >> p[i].second;
    sort (p + 1, p + n + 1, cmp);
    for (int i = 1; i <= n; i++)    p[i + n] = p[i];
    double ans = -1e9;

    for (int i = 1; i <= n; i++) {
        double sumx = 0, sumy = 0;
        for (int j = i; j < i + n; j++) {
            sumx += p[j].first, sumy += p[j].second;
            ans = max (ans, sqrt (sumx * sumx + sumy * sumy));
        }
    }
    cout << fixed << setprecision (11) << ans << endl;
}

//极角排序, 选连续的一段点一定是最优的
posted @ 2023-02-23 15:15  Sakana~  阅读(29)  评论(0编辑  收藏  举报