AtCoder Beginner Contest 144

AtCoder Beginner Contest 144

https://atcoder.jp/contests/abc144
补一下3.23做的。

D - Water Bottle

分类讨论,三角函数。

#include <bits/stdc++.h>
#define pi acos (-1)

using namespace std;

int main () {
    int a, b, x;
    cin >> a >> b >> x;
    cout << fixed << setprecision (7);
    if (2 * x < a * a * b)  cout << atan2 (b, 2.0 * x / (a * b)) * 180 / pi;
    else    cout << atan2 (2 * b - 2.0 * x / (1.0 * a * a), a) * 180 / pi;
}

E - Gluttony

非常简单的二分!

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

using namespace std;
const int N = 2e5 + 5;
ll n, k, a[N], b[N];

bool check (ll x) {
    //改a能否在k次之内使得最大值<=x
    ll cnt = 0;
    for (int i = 1; i <= n; i++) {
        if (a[i] * b[i] <= x)   continue;
        cnt += (a[i] * b[i] - x + b[i] - 1) / b[i];
    }
    return cnt <= k;
}

int main () {
    cin >> n >> k;
    for (int i = 1; i <= n; i++)    cin >> a[i];
    for (int i = 1; i <= n; i++)    cin >> b[i];
    sort (a + 1, a + n + 1), sort (b + 1, b + n + 1, greater<>());
    // for (int i = 1; i <= n; i++)    cout << a[i] << ' ';cout << endl;
    // for (int i = 1; i <= n; i++)    cout << b[i] << ' ';cout << endl;
    ll l = 0, r = 0;
    for (int i = 1; i <= n; i++)    r = max (r, a[i] * b[i]);
    while (l < r) {
        ll mid = l + r >> 1;
        if (check (mid))    r = mid;
        else    l = mid + 1;
    }
    cout << r << endl;
}

//二分

F - Fork in the Road

期望dp

枚举点 \(i\),每次删去其中 \(f_v\) 最大的出边 \(v\)

#include <bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;
const int N = 605, M = N * N, inf = 1e9;
int n, m;
double f[N], ans = inf; //f[i]:i到n的期望次数
vector<int> v[N];

double cal (int x) {
    for (int i = 1; i <= n; i++)    f[i] = 0.0;
    for (int i = n - 1; i >= 1; i--) {
        if (v[i].size () == 1 && x == i) { //注意删的是i的出边
            f[x] = inf; //所以如果i只有一条出边,删了就到不了
            continue;
        }
        f[i] = 1;
        int fm = v[i].size () - (x == i);
        double maxn = 0;
        for (auto j : v[i]) {
            double tt = f[j];
            maxn = max (maxn, tt);
            f[i] += tt / fm;
        }
        if (i == x) f[i] -= maxn / fm;
    }
    return f[1];
}

int main () {
    cin >> n >> m;
    while (m --) {
        int a, b;
        cin >> a >> b;
        v[a].push_back (b);
    }
    for (int i = 1; i <= n; i++)    ans = min (ans, cal (i)); //删掉i的出边v中fv最大的那个
    cout << fixed << setprecision (7) << ans << endl;
}

//枚举能删的
posted @ 2023-04-02 18:49  Sakana~  阅读(15)  评论(0编辑  收藏  举报