• Codeforces Round #670 (Div. 2) A


    题目链接

    A. Subset Mex

    思路:

    桶排记录一下每个数出现的次数。从小到大遍历。

    代码:
    /*
     * @Author       : nonameless
     * @Date         : 2020-09-12 21:33:31
     * @LastEditors  : nonameless
     * @LastEditTime : 2020-09-12 21:58:48
     */
    #include <bits/stdc++.h>
    #define x first
    #define y second
    #define pb push_back
    #define sz(x) (int)x.size()
    #define all(x) x.begin(), x.end()
    using namespace std;
    typedef long long ll;
    typedef pair<ll, ll> PLL;
    typedef pair<int, int> PII;
    typedef pair<double, double> PDD;
    const double eps = 1e-6;
    const double PI  = acos(-1.0);
    const int INF = 0x3f3f3f3f;
    const ll LNF  = 0x3f3f3f3f3f3f;
    inline void input(char &a  ) { cin >> a;          }
    inline void input(string &a) { cin >> a;          }
    inline void input(char * a ) { scanf("%s", a);    }
    inline void input(int &a   ) { scanf("%d", &a);   }
    inline void input(ll &a    ) { scanf("%lld", &a); }
    inline void input(double &a) { scanf("%lf", &a);  }
    inline void output(ll a    ) { printf("%lld
    ",a);}
    inline void output(int a   ) { printf("%d
    ",a);  }
    inline void output(char a  ) { printf("%c
    ",a);  }
    inline void output(char * a) { printf("%s
    ",a);  }
    inline void output(string a) { cout << a << endl; }
    inline int gcd(int a, int b) { return b ? gcd(b,a % b):a;}
    inline ll  gcd(ll  a, ll  b) { return b ? gcd(b,a % b):a;}
    inline int lcm(int a, int b) { return a * b / gcd(a, b); }
    
    const int N = 1e2 + 10;
    
    int arr[N];
    
    int main(){
    
        int t; input(t);
        while(t --){
            int n; input(n);
            memset(arr, 0, sizeof arr);
            for(int i = 1; i <= n; i ++){
                int x; input(x);
                arr[x] ++;
            }
            int a = -1, b = -1;
            for(int i = 0; i <= 100; i ++){
                if(a != -1 && b != -1) break;
                if(arr[i] == 0){
                    if(a == -1) a = i;
                    if(b == -1) b = i;
                } else if(arr[i] == 1){
                    if(a != -1 || b != -1) continue;
                    if(a == -1) { a = i; continue; }
                    if(b == -1) { b = i; }
                }
            }
            int mx = 0;
            for(int i = 0; i <= 100; i ++) if(arr[i] == 0) { mx = i; break; }
            //printf("a = %d b = %d
    ", a, b);
            output(max(mx, a + b));
        }
        return 0;
    }
    
    

    B. Maximum Product

    思路:

    一个很直接办法就是暴力枚举负数出现的个数。

    1. 负数出现了 (0) 个;
    2. 负数出现了 (2) 个;
    3. 负数出现了 (4) 个;
    4. 如果上面都不能满足,就说明答案 (leq 0) 的。

    注:(代码很丑,勿看)

    代码:
    /*
     * @Author       : nonameless
     * @Date         : 2020-09-12 22:02:46
     * @LastEditors  : nonameless
     * @LastEditTime : 2020-09-12 23:36:37
     */
    #include <bits/stdc++.h>
    #define x first
    #define y second
    #define pb push_back
    #define sz(x) (int)x.size()
    #define all(x) x.begin(), x.end()
    using namespace std;
    typedef long long ll;
    typedef pair<ll, ll> PLL;
    typedef pair<int, int> PII;
    typedef pair<double, double> PDD;
    const double eps = 1e-6;
    const double PI  = acos(-1.0);
    const int INF = 0x3f3f3f3f;
    const ll LNF  = 0x3f3f3f3f3f3f3f3f;
    inline void input(char &a  ) { cin >> a;          }
    inline void input(string &a) { cin >> a;          }
    inline void input(char * a ) { scanf("%s", a);    }
    inline void input(int &a   ) { scanf("%d", &a);   }
    inline void input(ll &a    ) { scanf("%lld", &a); }
    inline void input(double &a) { scanf("%lf", &a);  }
    inline void output(ll a    ) { printf("%lld
    ",a);}
    inline void output(int a   ) { printf("%d
    ",a);  }
    inline void output(char a  ) { printf("%c
    ",a);  }
    inline void output(char * a) { printf("%s
    ",a);  }
    inline void output(string a) { cout << a << endl; }
    inline int gcd(int a, int b) { return b ? gcd(b,a % b):a;}
    inline ll  gcd(ll  a, ll  b) { return b ? gcd(b,a % b):a;}
    inline int lcm(int a, int b) { return a * b / gcd(a, b); }
    
    const int N = 1e5 + 10;
    
    ll a[N];
    
    struct st{
        ll v;
        int f;
    }b[N];
    
    bool cmp(st p, st q) { return p.v > q.v; }
    
    int main(){
    
        int t; cin >> t; 
        while(t --){
            int n; cin >> n;
            int cd = 0;
            for(int i = 1; i <= n; i ++){
                cin >> a[i];
                if(a[i] < 0) {
                    b[++cd].v = -a[i];
                    b[cd].f = 0;
                } else if(a[i] > 0){
                    b[++cd].v = a[i];
                    b[cd].f = 1;
                }
                a[i] = abs(a[i]);
            }
            sort(b + 1, b + cd + 1, cmp);
            ll ans = -1e18, tmp1 = 1, tmp2 = 1, tmp3 = 1, tmp4 = 1;
            int mark = 0;
            for(int i = 1, j = 0; i <= cd; i ++){
                if(b[i].f){
                    tmp1 *= b[i].v;
                    j ++;
                }
                if(j == 5) { mark = 1; break; }
            }
            if(mark) ans = max(ans, tmp1);
            mark = 0;
            for(int i = 1, j = 0, k = 0; i <= cd; i ++){
                if(b[i].f && j < 3) {
                    tmp2 *= b[i].v;
                    j ++;
                } else if(b[i].f == 0 && k < 2){
                    tmp2 *= b[i].v;
                    k ++;
                }
                if(j == 3 && k == 2) { mark = 1; break; }
            }
            if(mark) { ans = max(ans, tmp2); mark = 0; }
            for(int i = 1, j = 0, k = 0; i <= cd; i ++){
                if(b[i].f && j < 1){
                    tmp3 *= b[i].v;
                    j ++;
                } else if(!b[i].f && k < 4){
                    tmp3 *= b[i].v;
                    k ++;
                }
                if(j == 1 && k == 4) { mark = 1; break; }
            }
            if(mark) { ans = max(ans, tmp3); mark = 0; }
            sort(a + 1, a + n + 1);
            for(int i = 1; i <= 5; i ++)  tmp4 *= a[i];
            ans = max(ans, -tmp4);
            cout << ans << endl;
        }
        return 0;
    }
    
    思路:

    根据题意可以理解:

    把某个点当作根,计算一下以儿子节点为根的子树的大小,取最小的值。

    然后每个点都要作为根节点算一遍,再在里面取最小,即是重心。

    那么我们 (dfs) 一遍就可以计算出来。

    注(一个颗树最多有两个重心,如果有就一定相连)

    • 一个重心就任意删去一条与重心相连的边
    • 两个重心就删去某个重心的儿子节点(该节点不是重心),然后该节点与另一个重心相连。
    代码:
    #include <bits/stdc++.h>
    #define x first
    #define y second
    #define pb push_back
    #define sz(x) (int)x.size()
    #define all(x) x.begin(), x.end()
    using namespace std;
    typedef long long ll;
    typedef pair<ll, ll> PLL;
    typedef pair<int, int> PII;
    typedef pair<double, double> PDD;
    const double eps = 1e-6;
    const double PI  = acos(-1.0);
    const int INF = 0x3f3f3f3f;
    const ll LNF  = 0x3f3f3f3f3f3f3f3f;
    inline void input(char &a  ) { cin >> a;          }
    inline void input(string &a) { cin >> a;          }
    inline void input(char * a ) { scanf("%s", a);    }
    inline void input(int &a   ) { scanf("%d", &a);   }
    inline void input(ll &a    ) { scanf("%lld", &a); }
    inline void input(double &a) { scanf("%lf", &a);  }
    inline void output(ll a    ) { printf("%lld
    ",a);}
    inline void output(int a   ) { printf("%d
    ",a);  }
    inline void output(char a  ) { printf("%c
    ",a);  }
    inline void output(char * a) { printf("%s
    ",a);  }
    inline void output(string a) { cout << a << endl; }
    inline int gcd(int a, int b) { return b ? gcd(b,a % b):a;}
    inline ll  gcd(ll  a, ll  b) { return b ? gcd(b,a % b):a;}
    inline int lcm(int a, int b) { return a * b / gcd(a, b); }
    
    const int N = 1e5 + 10;
    
    vector<int> g[N];
    
    int n;
    int cnt[N], sz[N];
    
    void dfs(int u, int fa){
        sz[u] = 1;
        for(auto it : g[u]){
            if(it == fa) continue;
            dfs(it, u);
            sz[u] += sz[it];
            cnt[u] = max(cnt[u], sz[it]);
        }
        cnt[u] = max(cnt[u], n - sz[u]);
    }
    
    int main(){
    
        int t; input(t);
        while(t --){
            input(n);
            memset(cnt, 0, sizeof cnt);
            memset(sz, 0, sizeof sz);
            for(int i = 1; i < n; i ++){
                int u, v; input(u); input(v);
                g[u].pb(v); g[v].pb(u);
            }
            dfs(1, 0);
            int mn = *min_element(cnt + 1, cnt + n + 1);
            int a = 0, b = 0;
            for(int i = 1; i <= n; i ++){
                if(cnt[i] == mn){
                    if(a) b = i;
                    else  a = i;
                }
            }
            if(b == 0){
                int t = g[a][0];
                printf("%d %d
    ", a, t);
                printf("%d %d
    ", a, t);
            } else{
                int t;
                for(auto it : g[b]) if(it != a)  { t = it; break; }
                printf("%d %d
    ", b, t);
                printf("%d %d
    ", a, t);
            }
            for(int i = 1; i <= n; i ++) g[i].clear();
        }
    
        
        return 0;
    }
    
    
  • 相关阅读:
    习题3.2三角形的知识1
    习题3.1三角形的知识2
    复习3.1三角形的知识1
    斜边和直角边公理、角的平分线11
    三角形全等的判定10
    全等三角形9
    你不知道的javascript(中卷)----读书笔记
    jquery----抽奖系统
    jQuery-----五子棋
    个人练手仿站
  • 原文地址:https://www.cnblogs.com/nonameless/p/13661319.html
Copyright © 2020-2023  润新知