Codeforces Round #635 (Div. 2)(A, B, C, D)

A. Ichihime and Triangle

A. Ichihime and Triangle 题目链接

直接输入 \(a, b, c, d\), 然后输出 \(b, c, c\) 就行了。

//Powered by CK
#include<bits/stdc++.h>
using namespace std;
int main() {
    int t, a, b, c, d;
    cin >> t;
    while(t--) {
        cin >> a >> b >> c >> d;
        printf("%d %d %d\n", b, c, c);  
    }
    return 0;
}

B. Kana and Dragon Quest game

B. Kana and Dragon Quest game 题目链接

思路

我们发现当 \(h < 20\) 的时候,操作 \(Void Absorption\) 只能让 h 变大,所以保证 \(h >= 20\) 并且操作 \(Void Absorption\) 有剩余的时候先进行。

//Powered by CK
#include<bits/stdc++.h>
using namespace std;
int main() {
    int t, a, b, c, d;
    cin >> t;
    while(t--) {
        cin >> a >> b >> c;
        while(a >= 20 && b--)
            a = a / 2 + 10;
        while(c--)  a -= 10;
        if(a <= 0)  puts("YES");
        else    puts("NO");
    }
    return 0;
}

C. Linova and Kingdom

C. Linova and Kingdom 题目链接

思路

我们可以知道,如果把一座城市当成工业城市,它会影响其子树上的点,我们定义两个数组,一个dis代表当前节点到根节点1的距离,si数组代表,当前节点的子树的节点数量。
通过贪心,也就是得到 \(dis - si\) 的前 \(k\) 项。

//Powered by CK
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
typedef long long ll;
int head[N], to[N], nex[N], cnt = 1;
int n, k, dis[N], si[N];
void add(int x, int y) {
    to[cnt] = y;
    nex[cnt] = head[x];
    head[x] = cnt++;
}
void dfs(int rt, int p) {
    si[rt] = 1;
    dis[rt] = dis[p] + 1;
    for(int i = head[rt]; i; i = nex[i]) {
        if(to[i] != p) {
            dfs(to[i], rt);
            si[rt] += si[to[i]];
        }
    }
    dis[rt] -= si[rt];
}
int main() {
    ios::sync_with_stdio(false);
    int x, y;
    cin >> n >> k;
    for(int i = 1; i < n; i++) {
        cin >> x >> y;
        add(x, y);
        add(y, x);
    }
    dfs(1, 0);
    sort(dis + 1, dis + n + 1, greater<int> ());
    ll ans = 0;
    for(int i = 1; i <= k; i++)
        ans += dis[i];
    cout << ans << endl;
    return 0;
}

D. Xenia and Colorful Gems

D. Xenia and Colorful Gems 题目链接

思路

总共有三组数,要求 \((x−y)^2+(y−z)^2+(z−x)^2\) 最小值,我们不妨设 a 在第一组数里面,b 在第二组数里面,c 在第三组数里面。

共有如下几种情况

  • \(a <= b <= c\)
  • \(a <= c <= b\)
  • \(b <= a <= c\)
  • \(b <= c <= a\)
  • \(c <= a <= b\)
  • \(c <= b <= a\)

我们考虑枚举中间的数,然后让两边的数趋近于它,这样最后得到的结果就一定满足条件。

//Powered by CK
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>

using namespace std;
typedef long long ll;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e5 + 10;

ll a[N], b[N], c[N];
int n1, n2, n3, t;
ll get_min(ll x, ll y, ll z) {
    return (x - y) * (x - y) + (y - z) * (y - z) + (z - x) * (z - x);
}
int main() {
    // freopen("in.txt", "r", stdin);
    ios::sync_with_stdio(false);
    int t, n[3];
    vector<int> a[3];
    cin >> t;
    while(t--) {
        cin >> n[0] >> n[1] >> n[2];
        for(int i = 0; i < 3; i++) {
            a[i].resize(n[i]);
            for(int j = 0; j < n[i]; j++)
                cin >> a[i][j];
            sort(a[i].begin(), a[i].end());
        }
        ll ans = INF;
        for(int i = 0; i < 3; i++)//我们枚举的顺序是k <= i <= j
            for(int j = 0; j < 3; j++)
                for(int k = 0; k < 3; k++) {
                    if(i == j || i == k || j == k)  continue;
                    for(vector<int> :: iterator x = a[i].begin(); x != a[i].end(); x++) {//注意这里存在lower_bound 和upper_bound
                        auto y = lower_bound(a[j].begin(), a[j].end(), *x);//保证j >= i
                        auto z = upper_bound(a[k].begin(), a[k].end(), *x);//这里保证z--,转换也就是k <= i。
                        if(y != a[j].end() && z != a[k].begin())
                            z--, ans = min(ans, get_min(*x, *y, *z));
                    }
                }
        cout << ans << endl;
    }
    return 0;
}
posted @ 2020-04-16 16:48  lifehappy  阅读(147)  评论(0编辑  收藏  举报