• 牛客假日团队赛8


    牛客假日团队赛8


    A Cell Phone Network

    • 思路:最小支配集

    • AC代码


    #include<stdio.h>
    #include<iostream>
    #include<math.h>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    #include<set>
    #include<string>
    #include<sstream>
    typedef long long ll;
    typedef unsigned long long ull;
    using namespace std;
     
    ll Pow_mod(ll a, ll b, ll c){
        ll ans = 1;
        a %= c;
        while (b){
            if (b & 1) ans = (ans * a) % c;
            a = (a * a) % c;
            b >>= 1;
        }
        return (ans % c);
    }
     
    ll Pow(ll a, ll b){
        ll ans = 1;
        while (b){
            if (b & 1) ans *= a;
            a *= a;
            b >>= 1;
        }
        return ans;
    }
     
    int gcd(int a, int b){
        return b ? gcd(b, a % b) : a;
    }
     
    int lcm(int a, int b){
        return a * 1ll / gcd(a, b) * b;
    }
     
    const int N = 10010;
     
    int p[N];           // 父节点编号
    bool vis[N];        // dfs判重
    int newpos[N];      // newpos[i]表示dfs序列的第i个点是哪个点
    int now;            // 表示dfs序列已有点数
    bool s[N];          // 判断是否被覆盖
    bool se[N];         // se[i]表示点i属于要求的集合
    int head[N];
    int n, u, v, ans, tot;
     
    struct node{
        int to, next;
    }edge[N << 1];
     
    void dfs(int x){
        newpos[++ now] = x;
        for (int i = head[x]; i; i = edge[i].next){
            if (!vis[edge[i].to]){
                vis[edge[i].to] = true;
                p[edge[i].to] = x;
                dfs(edge[i].to);
            }
        }
    }
     
    void greedy(){
        for (int i = n; i >= 1; i -- ){
            int t = newpos[i];
            if (!s[t]){
                if (!se[p[t]]){
                    se[p[t]] = true;
                    ans ++;
                }
                s[t] = true;
                s[p[t]] = true;
                s[p[p[t]]] = true;
            }
        }
    }
     
    void add_edge(int u, int v){
        edge[++ tot].to = v;
        edge[tot].next = head[u];
        head[u] = tot;
    }
     
    int main(){
        scanf("%d", &n);
        for (int i = 1; i < n; i ++ ){
            scanf("%d%d", &u, &v);
            add_edge(u, v);
            add_edge(v, u);
        }
        p[1] = 1, vis[1] = 1,
        dfs(1);
        greedy();
        printf("%d
    ", ans);
        return 0;
    }
    

    B iCow

    • 思路:模拟 题意明确 按着题目分配就行了

    • AC代码


    #include<stdio.h>
    #include<iostream>
    #include<math.h>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    #include<set>
    #include<string>
    #include<sstream>
    typedef long long ll;
    typedef unsigned long long ull;
    using namespace std;
     
    ll Pow_mod(ll a, ll b, ll c){
        ll ans = 1;
        a %= c;
        while (b){
            if (b & 1) ans = (ans * a) % c;
            a = (a * a) % c;
            b >>= 1;
        }
        return (ans % c);
    }
     
    ll Pow(ll a, ll b){
        ll ans = 1;
        while (b){
            if (b & 1) ans *= a;
            a *= a;
            b >>= 1;
        }
        return ans;
    }
     
    int gcd(int a, int b){
        return b ? gcd(b, a % b) : a;
    }
     
    int lcm(int a, int b){
        return a * 1ll / gcd(a, b) * b;
    }
     
    const int N = 1010;
     
    int n, t, maxr, pos_, divi, rem;
     
    struct cow{
        int r, pos;
    }cows[N];
     
    int main(){
        scanf("%d%d", &n, &t);
        for (int i = 1; i <= n; i ++ ){
            scanf("%d", &cows[i].r);
            cows[i].pos = i;
        }
        while (t -- ){
            maxr = 0;
            pos_ = 0;
            for (int i = 1; i <= n; i ++ ){
                if (cows[i].r > maxr){
                    maxr = cows[i].r;
                    pos_ = cows[i].pos;
                }
            }
            cows[pos_].r = 0;
            divi = maxr / (n - 1);
            rem = maxr % (n - 1);
            printf("%d
    ", pos_);
            for (int i = 1; i <= n; i ++ ){
                if (i == pos_) continue;
                cows[i].r += divi;
            }
            for (int i = 1; i <= rem; i ++ ){
                if (i == pos_) rem ++;
                else cows[i].r += 1;
            }
        }
        return 0;
    }
    

    C 阶乘之和

    • 思路:直接用python过的

    • AC代码


    n = input()
    n = int(n)
    fact = 1
    sum = 0
    i = 1
    while n >= i:
        fact = fact * i
        sum = sum + fact
        i = i + 1
    print(sum)
    

    D Artificial Lake

    • 思路:模拟(队友写的

    • AC代码


    #include <bits/stdc++.h>
    #include <iostream>
    #include <cstring>
    #include <stack>
    #include <cstdlib>
    #include <queue>
    #include <cmath>
    #include <cstdio>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <list>
    #include <iterator>
    #include <set>
    #include <map>
    #include <utility>
    #include <iomanip>
    #include <ctime>
    #include <sstream>
    #include <bitset>
    #include <deque>
    #include <limits>
    #include <numeric>
    #include <functional>
    #define gc getchar()
    #define mem(a) memset(a,0,sizeof(a))
    #define mod 1000000007
    #define sort(a,n,int) sort(a,a+n,less<int>())
    #define fread() freopen("in.in","r",stdin)
    #define fwrite() freopen("out.out","w",stdout)
     
    #define PI acos(-1.0)
    #define N 100005
    #define MOD 2520
    #define E 1e-12
     
    typedef long long ll;
    typedef char ch;
    typedef double db;
    const long long  INF = 0x3f3f3f3f3f3f3f3f;
     
    using namespace std;
     
     
    struct node
    {
        ll w , h;
        int l , r;
    }a[N];
     
    int n = 0;
    long long res[N] = {0};
     
    int lowest()
    {
        ll minv = INF , pos = 0;
        for(int i = 1;i <= n;i++)
            if(a[i].h < minv)
            {
                minv = a[i].h;
                pos = i;
            }
        return pos;
    }
    int update(int position)
    {
        for(int i = 0;i<n;i++)
        {
            int left = a[position].l , right = a[position].r;
             
            if(a[left].h < a[position].h)
                position = left;
            else if(a[right].h < a[position].h)
                position = right;
            else
                return position;
        }
    }
    void guanshui(int position)
    {
        int counter = 1;
        long long  sum = 0;
        while(counter <= N)
        {
            counter++;
            sum += a[position].w;
            res[position] = sum;
            int l = a[position].l , r = a[position].r;
            sum += (min(a[l].h , a[r].h) - a[position].h - 1) * a[position].w;
      
            a[l].r = r;
            a[r].l = l;
             
            if(a[l].h < a[r].h)
            {
                a[l].w += a[position].w;
                position = l;
            }
            else
            {
                a[r].w += a[position].w;
                position = r;
            }
            position = update(position);
        }
    }
    int main()
    {
        cin >> n;
        int position = 0;
        for(int i = 1;i <= n;i++)
        {      
            cin >> a[i].w >> a[i].h;
        }
        for(int i = 0;i <= n+1;i++)
        {
            a[i].l = i-1;
            a[i].r = i+1;
        }
        a[0].w = 1;    
        a[0].h = INF;  
         
        a[n+1].w = 1;  
        a[n+1].h = INF;
         
        position = lowest();
        guanshui(position);
        for(int i = 1;i <= n;i++)
        {
            cout << res[i] << endl;
        }
        return 0;
    }
    

    E Haybale Guessing

    • 思路:并查集+区间染色

    • AC代码


    #include<stdio.h>
    #include<iostream>
    #include<math.h>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    #include<set>
    #include<string>
    #include<sstream>
    typedef long long ll;
    typedef unsigned long long ull;
    using namespace std;
     
    ll Pow_mod(ll a, ll b, ll c){
        ll ans = 1;
        a %= c;
        while (b){
            if (b & 1) ans = (ans * a) % c;
            a = (a * a) % c;
            b >>= 1;
        }
        return (ans % c);
    }
     
    ll Pow(ll a, ll b){
        ll ans = 1;
        while (b){
            if (b & 1) ans *= a;
            a *= a;
            b >>= 1;
        }
        return ans;
    }
     
    int gcd(int a, int b){
        return b ? gcd(b, a % b) : a;
    }
     
    int lcm(int a, int b){
        return a * 1ll / gcd(a, b) * b;
    }
     
    const int N = 1e6 + 10;
     
    int n, q, ans;
    int prt[N];         // prt[i] = j 表示区间 [j + 1, i] 被覆盖
    int fa[N];
     
    struct node_{
        int l, r, A;
    }seg[N];
     
    bool cmp(int a, int b){
        if (seg[a].A == seg[b].A){
            if (seg[a].l == seg[b].l) return seg[a].r < seg[b].r;
            return seg[a].l < seg[b].l;
        }
        return seg[a].A > seg[b].A;
    }
     
    int find(int x){
        return fa[x] == x ? x : fa[x] = find(fa[x]);
    }
     
    bool judge(int mid){
        for (int i = 1; i <= mid; i ++ ) prt[i] = i;
        for (int i = 1; i <= n; i ++ ) fa[i] = i;
        sort(prt + 1, prt + mid + 1, cmp);
        for (int i = 1; i <= mid; i ++ ){
            int A = seg[prt[i]].A;
            int l = seg[prt[i]].l, r = seg[prt[i]].r, L = l, R = r;             // [l, r]为交集 [L, R]为并集
            while (i + 1 <= mid && A == seg[prt[i + 1]].A){
                ++ i;
                if (seg[prt[i]].l > r) return false;
                l = max(l, seg[prt[i]].l);
                r = min(r, seg[prt[i]].r);
                L = min(L, seg[prt[i]].l);
                R = max(R, seg[prt[i]].r);
            }
            int x = find(l), y = find(r);
            if ((l != r && x == y && y != r) || (l == r && y != r)) return false;
            x = L, y = R;
            int flag = find(y + 1);
            while (flag != find(x)){
                int find_x = find(x);
                fa[find_x] = fa[find_x + 1];
            }
        }
        return true;
    }
     
    int main(){
        scanf("%d%d", &n, &q);
        for (int i = 1; i <= q; i ++ )
            scanf("%d%d%d", &seg[i].l, &seg[i].r, &seg[i].A);
        int l = 1, r = q + 1;
        while (r - l > 1){
            int mid = (l + r) >> 1;
            if (judge(mid))
                l = mid;
            else
                r = mid;
        }
        if (l == q) ans = 0;
        else ans = l + 1;
        printf("%d
    ", ans);
        return 0;
    }
    

    F Telephone Lines

    • 思路:最短路 spfa+二分

    • AC代码


    #include<iostream>
    #include<math.h>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    #include<set>
    #include<string>
    #include<sstream>
    typedef long long ll;
    typedef unsigned long long ull;
    using namespace std;
     
    ll Pow_mod(ll a, ll b, ll c){
        ll ans = 1;
        a %= c;
        while (b){
            if (b & 1) ans = (ans * a) % c;
            a = (a * a) % c;
            b >>= 1;
        }
        return (ans % c);
    }
     
    ll Pow(ll a, ll b){
        ll ans = 1;
        while (b){
            if (b & 1) ans *= a;
            a *= a;
            b >>= 1;
        }
        return ans;
    }
     
    int gcd(int a, int b){
        return b ? gcd(b, a % b) : a;
    }
     
    int lcm(int a, int b){
        return a * 1ll / gcd(a, b) * b;
    }
     
    const int N = 1010;
     
    queue<int> q;
    int n, p, k, tot, u, v, w, l, r, mid, ans;
    int head[N], dist[N];
    bool vis[N];
     
    struct node{
        int to, w, next;
    }edge[N << 5];
     
    inline void add_edge(int u, int v, int w){
        edge[++ tot].to = v;
        edge[tot].w = w;
        edge[tot].next = head[u];
        head[u] = tot;
    }
     
    inline bool spfa(ll x){
        memset(dist, 0x3f, sizeof(dist));
        memset(vis, false, sizeof(vis));
        dist[1] = 0;
        vis[1] = true;
        q.push(1);
        while (!q.empty()){
            int u = q.front();
            q.pop();
            vis[u] = false;
            for (int i = head[u]; i; i = edge[i].next){
                int v = edge[i].to;
                if (dist[v] > dist[u] + (edge[i].w > x ? 1 : 0)){
                    dist[v] = dist[u] + (edge[i].w > x ? 1 : 0);
                    if (!vis[v]){
                        vis[v] = true;
                        q.push(v);
                    }
                }
            }
        }
        return dist[n] <= k;
    }
     
    int main(){
        l = 0, r = 0;
        ans = -1;
        scanf("%d%d%d", &n, &p, &k);
        for (int i = 1; i <= p; i ++ ){
            scanf("%d%d%d", &u, &v, &w);
            add_edge(u, v, w);
            add_edge(v, u, w);
            r = max(r, w);
        }
        while (l <= r){
            mid = (l + r) >> 1;
            if (spfa(mid)){
                ans = mid;
                r = mid - 1;
            }
            else l = mid + 1;
        }
        printf("%d
    ", ans);
        return 0;
    }
    

    G Election Time

    • 思路:排两次序就出来了

    • AC代码


    #include<stdio.h>
    #include<iostream>
    #include<math.h>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    #include<set>
    #include<string>
    #include<sstream>
    typedef long long ll;
    typedef unsigned long long ull;
    using namespace std;
     
    ll Pow_mod(ll a, ll b, ll c){
        ll ans = 1;
        a %= c;
        while (b){
            if (b & 1) ans = (ans * a) % c;
            a = (a * a) % c;
            b >>= 1;
        }
        return (ans % c);
    }
     
    ll Pow(ll a, ll b){
        ll ans = 1;
        while (b){
            if (b & 1) ans *= a;
            a *= a;
            b >>= 1;
        }
        return ans;
    }
     
    int gcd(int a, int b){
        return b ? gcd(b, a % b) : a;
    }
     
    int lcm(int a, int b){
        return a * 1ll / gcd(a, b) * b;
    }
     
    const int N = 500010;
     
    int n, k;
     
    struct cow{
        int pos, a, b;
    }cows[N];
     
    int cmp1(cow x, cow y){
        return x.a > y.a;
    }
     
    int cmp2(cow x, cow y){
        return x.b > y.b;
    }
     
    int main(){
        scanf("%d%d", &n, &k);
        for (int i = 1; i <= n; i ++ ){
            scanf("%d%d", &cows[i].a, &cows[i].b);
            cows[i].pos = i;
        }
        sort(cows + 1, cows + n + 1, cmp1);
        sort(cows + 1, cows + k + 1, cmp2);
        printf("%d
    ", cows[1].pos);
        return 0;
    }
    

    H Costume Party

    • 思路:数据很水 可以直接暴力过 可以二分或状态压缩

    • AC代码


    #include<stdio.h>
    #include<iostream>
    #include<math.h>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    #include<set>
    #include<string>
    #include<sstream>
    typedef long long ll;
    typedef unsigned long long ull;
    using namespace std;
     
    ll Pow_mod(ll a, ll b, ll c){
        ll ans = 1;
        a %= c;
        while (b){
            if (b & 1) ans = (ans * a) % c;
            a = (a * a) % c;
            b >>= 1;
        }
        return (ans % c);
    }
     
    ll Pow(ll a, ll b){
        ll ans = 1;
        while (b){
            if (b & 1) ans *= a;
            a *= a;
            b >>= 1;
        }
        return ans;
    }
     
    int gcd(int a, int b){
        return b ? gcd(b, a % b) : a;
    }
     
    int lcm(int a, int b){
        return a * 1ll / gcd(a, b) * b;
    }
     
    const int N = 20010;
     
    int n, s, cnt, ans;
    int L[N];
     
    int main(){
        scanf("%d%d", &n, &s);
        for (int i = 1; i <= n; i ++ ) scanf("%d", &L[i]);
        sort(L + 1, L + n + 1);
        for (int i = 1; i <= n; i ++ ){
            while (cnt + 1 < i && L[i] + L[cnt + 1] <= s) cnt ++;
            while (cnt >= 1 && L[i] + L[cnt] > s) cnt --;
            ans += cnt;
        }
        printf("%d
    ", ans);
        return 0;
    }
    

    I Cantor表

    • 思路:模拟

    • AC代码


    #include<stdio.h>
    #include<iostream>
    #include<math.h>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    #include<set>
    #include<string>
    #include<sstream>
    typedef long long ll;
    typedef unsigned long long ull;
    using namespace std;
     
    ll Pow_mod(ll a, ll b, ll c){
        ll ans = 1;
        a %= c;
        while (b){
            if (b & 1) ans = (ans * a) % c;
            a = (a * a) % c;
            b >>= 1;
        }
        return (ans % c);
    }
     
    int gcd(int a, int b){
        return b ? gcd(b, a % b) : a;
    }
     
    int lcm(int a, int b){
        return a * 1ll / gcd(a, b) * b;
    }
     
    int n, k, s;
     
    int main(){
        scanf("%d", &n);
        while (s < n){
            k ++;
            s += k;
        }
        if (k & 1) printf("%d/%d
    ", s - n + 1, n + k - s);
        else printf("%d/%d
    ", n + k - s, s - n + 1);
        return 0;
    }
    

    J Running

    • 思路:dp

    • AC代码


    #include<stdio.h>
    #include<iostream>
    #include<math.h>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    #include<set>
    #include<string>
    #include<sstream>
    typedef long long ll;
    typedef unsigned long long ull;
    using namespace std;
     
    ll Pow_mod(ll a, ll b, ll c){
        ll ans = 1;
        a %= c;
        while (b){
            if (b & 1) ans = (ans * a) % c;
            a = (a * a) % c;
            b >>= 1;
        }
        return (ans % c);
    }
     
    ll Pow(ll a, ll b){
        ll ans = 1;
        while (b){
            if (b & 1) ans *= a;
            a *= a;
            b >>= 1;
        }
        return ans;
    }
     
    int gcd(int a, int b){
        return b ? gcd(b, a % b) : a;
    }
     
    int lcm(int a, int b){
        return a * 1ll / gcd(a, b) * b;
    }
     
    const int N = 20010;
    const int M = 510;
     
    int n, m, ans;
    int dp[N][M], d[N];
     
    int main(){
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i ++ ) scanf("%d", &d[i]);
        dp[1][1] = d[1];
        for (int i = 1; i <= n; i ++ ){
            for (int j = 0; j <= min(m, i); j ++ ){
                if (j == 0) dp[i][0] = max(dp[i][0], dp[i - 1][0]);
                else dp[i + j][0] = max(dp[i + j][0], dp[i][j]);                    // 休息
                dp[i + 1][j + 1] = max(dp[i + 1][j + 1], dp[i][j] + d[i + 1]);      // 不休息
            }
        }
    //    for (int i = 0; i <= m; i ++ )
    //        printf("%d
    ", dp[n][i]);
        ans = dp[n][0];
        printf("%d
    ", ans);
        return 0;
    }
    

    K Cow Contest

    • 思路:传递闭包 floyd就行

    • AC代码


    #include<stdio.h>
    #include<iostream>
    #include<math.h>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    #include<set>
    #include<string>
    #include<sstream>
    typedef long long ll;
    typedef unsigned long long ull;
    using namespace std;
     
    ll Pow_mod(ll a, ll b, ll c){
        ll ans = 1;
        a %= c;
        while (b){
            if (b & 1) ans = (ans * a) % c;
            a = (a * a) % c;
            b >>= 1;
        }
        return (ans % c);
    }
     
    ll Pow(ll a, ll b){
        ll ans = 1;
        while (b){
            if (b & 1) ans *= a;
            a *= a;
            b >>= 1;
        }
        return ans;
    }
     
    int gcd(int a, int b){
        return b ? gcd(b, a % b) : a;
    }
     
    int lcm(int a, int b){
        return a * 1ll / gcd(a, b) * b;
    }
     
    const int N = 110;
    const int M = 4510;
     
    int n, m, u, v, cnt, ans;
    int mp[N][N];
     
    int main(){
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= m; i ++ ){
            scanf("%d%d", &u, &v);
            mp[u][v] = 1;
        }
        for (int k = 1; k <= n; k ++ )
            for (int i = 1; i <= n; i ++ )
                for (int j = 1; j <= n; j ++ )
                    mp[i][j] = mp[i][j] || (mp[i][k] && mp[k][j]);
        for (int i = 1; i <= n; i ++ ){
            cnt = 0;
            for (int j = 1; j <= n; j ++ )
                if (mp[i][j] || mp[j][i])
                    cnt ++;
            if (cnt == n - 1) ans ++;
        }
        printf("%d
    ", ans);
        return 0;
    }
    

    L 幂次方

    • 思路:模拟

    • AC代码


    #include<stdio.h>
    #include<iostream>
    #include<math.h>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    #include<set>
    #include<string>
    #include<sstream>
    typedef long long ll;
    typedef unsigned long long ull;
    using namespace std;
     
    ll Pow_mod(ll a, ll b, ll c){
        ll ans = 1;
        a %= c;
        while (b){
            if (b & 1) ans = (ans * a) % c;
            a = (a * a) % c;
            b >>= 1;
        }
        return (ans % c);
    }
     
    ll Pow(ll a, ll b){
        ll ans = 1;
        while (b){
            if (b & 1) ans *= a;
            a *= a;
            b >>= 1;
        }
        return ans;
    }
     
    int gcd(int a, int b){
        return b ? gcd(b, a % b) : a;
    }
     
    int lcm(int a, int b){
        return a * 1ll / gcd(a, b) * b;
    }
     
    int n;
    bool flag;
    string s[16]={"2(0)", "2", "2(2)", "2(2+2(0))",
                  "2(2(2))", "2(2(2)+2(0))", "2(2(2)+2)", "2(2(2)+2+2(0))",
                  "2(2(2+2(0)))", "2(2(2+2(0))+1)", "2(2(2+2(0))+2)", "2(2(2+2(0))+2+2(0))",
                  "2(2(2+2(0))+2(2))", "2(2(2+2(0))+2(2)+2(0))", "2(2(2+2(0))+2(2)+2)", "2(2(2+2(0))+2(2)+2+2(0))"};
     
    int main(){
        scanf("%d", &n);
        for (int i = 15; i >= 0; i -- ){
            if (Pow(2, i) <= n){
                n -= Pow(2, i);
                if (flag) printf("+");
                cout<<s[i];
                flag = true;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    android开发布局三(微信布局)
    Android开发adb,SQLite数据库运用
    直线电机磁负荷、电负荷
    MIT公开课(一):电场和偶极子
    哈工大电气工程系硕士研究生入学复试——自动控制原理1、2章
    直线电机与旋转电机的区别
    Math类介绍
    Scala编辑器和IntelliJ IDEA开发环境配置
    减少cpu的方法
    AS内存清理,建议以及查找内存泄露的方法
  • 原文地址:https://www.cnblogs.com/Misuchii/p/11287033.html
Copyright © 2020-2023  润新知