zoukankan      html  css  js  c++  java
  • 牛客假日团队赛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 按键消息处理
    objcopy
    SQLite多线程读写实践及常见问题总结
    android动画坐标定义
    Android动画效果translate、scale、alpha、rotate
    Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运行 Java公共类)
    Flatten Binary Tree to Linked List
    Distinct Subsequences
    Populating Next Right Pointers in Each Node II
    Populating Next Right Pointers in Each Node
  • 原文地址:https://www.cnblogs.com/Misuchii/p/11287033.html
Copyright © 2011-2022 走看看