zoukankan      html  css  js  c++  java
  • AIM Tech Round 3 (Div. 2) (B C D E) (codeforces 709B 709C 709D 709E)

    rating又掉下去了。好不容易蓝了。。。。

    A。。没读懂题,wa了好几次,明天问队友补上。。。

    B. Checkpoints

    题意:一条直线上n个点x1,x2...xn,现在在位置a,求要经过任意n-1个点的最小路程

    题解:分类讨论,乱搞搞总会出来的,我大概写的很笨……

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int x[100005];
    
    ll cal(ll x, ll a, ll z) {
        return min((a-x)*2+(z-a) , (z-a)*2+(a-x));
    }
    
    int main() {
        int n, a;
        scanf("%d%d", &n, &a);
        for (int i = 0; i < n; ++i) {
            scanf("%d", x+i);
        }
        sort(x, x+n);
        ll ans = 1e18, tmp;
    
        if (n == 1) cout << 0;
        else if (n == 2) cout << min(abs(a-x[0]), abs(a-x[1]));
        else if (a >= x[n-1]) cout << a-x[1];
        else if (a <= x[0]) cout << x[n-2]-a;
        else if (a <= x[1]) cout << min(cal(x[0], a, x[n-2]), (ll)(x[n-1]-a));
        else if (a > x[n-2]) cout << min(cal(x[1], a, x[n-1]), (ll)(a-x[0]));
        else cout << min(cal(x[0],a,x[n-2]), cal(x[1],a,x[n-1]));
        return 0;
    }

    C. Letters Cyclic Shift

    题意:给一个字符串,要求替换任意一个非空字串,使得替换后字串字典序最小。替换的方法是z->y,y->x,....,b->a,a->z

    题解:C题怎么会这么简单。。。很容易想到替换尽可能靠前的字符,而且不能替换a,注意题目要求的必须替换一个字串,所以字串中所有字母都是a的时候,只能把最后一个变成z了。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    char a[100005];
    int main() {
        while (cin >> a) {
            bool fg = false;
            int n = strlen(a);
            int cnt = 0;
            for (int i = 0; i < n; ++i) {
                if (a[i] != 'a') {a[i]--; fg=true;}
                else if(fg) break;
            }
            if (!fg) a[n-1] = 'z';
            cout << a << endl;
        }
    
        return 0;
    }

    D. Recover the String

    题意:对于一个只有0和1的序列,会有很多00,01,10,11的子序列,现在给你00,01,10,11的子序列的数量,求符合要求的子串,没有输出Impossible

    题解:注意,子序列不同于子串,不连续。

    设子串中0的数量是x,那么00的数量一定是C(2,x),1同理。然后设0的数量是x,1的数量是y,所以所有子序列的个数是C(2,x+y),即C(2,x+y)==a+b+c+d,如果不相等则不可能构成。要注意的地方是当00的数量为0的时候,x既可以为0,也可以为1,需要根据bc判断。y同理。

    至于字符串的构造,有点贪心的想法。瞎搞的。。。。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    char ans[1000005];
    int main() {
        ll a, b, c, d;
        while (cin >> a >> b >> c >> d) {
            ll x = (ll)sqrt(a*2)+1;
            ll y = (ll)sqrt(d*2)+1;
            if (a+b+c+d == 0) {
                puts("0");
                continue;
            }
            if (a == 0) {
                if (b || c) x = 1; else x = 0;
            }
            if (d == 0) {
                if (b || c) y = 1; else y = 0;
            }
            if (!(x*(x-1) == a*2 && y*(y-1) == d*2)) {
                puts("Impossible");
                continue;
            }
            ll n = x+y;
            ll xnt = n*(n-1)/2-a-d;
            if (b+c != xnt) {
                puts("Impossible");
                continue;
            }
            int idx = 0;
            int cnt = x+y;
            while (cnt) {
                if (b < y) {
                    ans[idx++] = '1';
                    c -= x;
                    y--;
                } else if (c < x) {
                    ans[idx++] = '0';
                    b -= y;
                    x--;
                } else if (b >= c) {
                    ans[idx++] = '0';
                    b -= y;
                    x--;
                } else {
                    ans[idx++] = '1';
                    c -= x;
                    y--;
                }
                cnt--;
            }
            ans[idx] = 0;
            printf("%s
    ", ans);
        }
        return 0;
    }

    E. Centroids

    题意:给一棵树,对于每一个结点,可不可以通过在树上去掉一条边再增加一条边(必须还是一棵树),使这个结点成为这棵树的重心。
    题解:%%%明神

    对于一个点,如果不能当重心,一定是它有一棵子树u,size[u]>n/2,那么只要在这个子树u中找到一个子树v,满足size[v]<=n/2且size[u]-size[v]<=n/2就可以了。

    于是树形dp,求每个点的<=n/2的最大子树的大小。

    至于向上思想类似,随便搞搞,具体看代码。

    不喜欢用邻接表存图,看起来很麻烦,可是vector确实会慢一些,比赛一定不能用=。=

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    const int N = 400005;
    
    vector<int> g[N];
    int sz[N], up[N], dn[N]; // up向上的最大的不大于n/2的子树大小 dn向下的
    int ans[N];
    int n;
    
    inline int read()
    {
        char ch = getchar();
        int data = 0;
        while (ch < '0' || ch > '9')
            ch = getchar();
        do {
            data = data*10 + ch-'0';
            ch = getchar();
        } while (ch >= '0' && ch <= '9');
        return data;
    }
    
    void UP(int &x, int y) { if(y>x) x=y; }
    void dfs(int u, int fa) { // 第一遍向下dfs
        sz[u] = 1;
        for (int i = 0; i < g[u].size(); ++i) {
            int v = g[u][i];
            if (v == fa) continue;
            dfs(v, u);
            if (sz[v] - dn[v] > n/2) ans[u] = 0;
            sz[u] += sz[v];
            UP(dn[u], dn[v]);
        }
        if (sz[u] <= n/2) dn[u] = sz[u];
    }
    void dfs1(int u, int fa) { // 第二遍向上
        if (n-sz[u] - up[u] > n/2) ans[u] = 0;
        if (n-sz[u] <= n/2) up[u] = n-sz[u];
    
        int mx = 0; // 对于每一个结点向上的最大值 可能来自向上的链 也可能来自父节点的其他子树
        // mx记录的就父节点其他子树的最大值
        for (int i = 0; i < g[u].size(); ++i) {
            int v = g[u][i];
            if (v == fa) continue;
            up[v] = max(up[u], mx);
            UP(mx, dn[v]);
        }
        mx = 0;
        for (int i = g[u].size()-1; i >= 0; --i) {
            int v = g[u][i];
            if (v == fa) continue;
            UP(up[v], mx);
            UP(mx, dn[v]);
            dfs1(v, u);
        }
    }
    
    int main() {
        scanf("%d", &n);
        int u, v;
        for (int i = 1; i < n; ++i) {
            u = read(); v = read();
            g[u].push_back(v);
            g[v].push_back(u);
        }
        if (n == 2) { printf("1 1"); return 0; }
    
        for (int i = 1; i <= n; ++i) ans[i] = 1;
        dfs(1, 0);
        dfs1(1, 0);
        for (int i = 1; i <= n; ++i) {
            printf("%d", ans[i]);
            if (i != n) printf(" ");
        }
        return 0;
    }
  • 相关阅读:
    10-vue自定义指令
    09-vue过滤器的基本使用
    vue总结
    07-vue的v-if和v-show
    06-循环数组v-for
    Java通过JNA调用dll或so
    Centos7安装FRP内网穿透工具进行远程连接
    centos7检查Java项目存活与否并重启
    centos7中Java项目重启
    Ubuntu 19.04: Connect to GNOME desktop environment via XRDP
  • 原文地址:https://www.cnblogs.com/wenruo/p/5808492.html
Copyright © 2011-2022 走看看