• [牛客小\白月赛40] A, D, E, F, G, I


    不是很理解CSDN连小白(标题违规???)都容不下了么


    A数字游戏https://ac.nowcoder.com/acm/contest/11217/A

    用到了非递归快速幂(怕超时)和位运算

    #include<stdio.h>
    typedef long long ll;
    
    ll Quick_pow(int a,int n)
    {
        int ans = 1;
        while(n)
        {
            if(n&1)
                ans *= a;
            a *= a;
            n >>= 1;
        }
        return ans;
    }
    int main()
    {
        int t, x;
        scanf("%d",&t);
        while(t--)
        {
            int cnt=0;
            scanf("%d",&x);
            int y=x;
            while(y)
            {
                int f=y;
                int cnt1=0,cntAll=0;;
                while(f){
                    if(f&1) cnt1++;
                    f >>= 1;
                    cntAll++;
                }
                if(cnt1&1){
                    if(y&1) y--;
                    else y ++;
                }else{
                     y-=Quick_pow(2,cntAll-1);
                }
                cnt++;
            }
            printf("%d\n",cnt);
        }
        return 0;
    }

    D优美字符串https://ac.nowcoder.com/acm/contest/11217/D

    签到题, 相邻重复数量+字符串长度

    #include<iostream>
    using namespace std;
    
    int main()
    {
        int t;
        cin >> t;
        string s;
        while(t--)
        {
            cin >>s;
            int cnt = 0;
            for(int i = 0; i < s.length()-1;i ++)
                if(s[i]==s[i+1]) cnt++;
            cout << s.length()+cnt <<endl;
        }
        return 0;
    }

    E分组https://ac.nowcoder.com/acm/contest/11217/E

    二分, 二分尽可能多的小组人数(即题中的n), 通过限定组数更新左右区间, 最后需要验证组数是否满足

    #include<iostream>
    using namespace std;
    
    const int N = 1e5+10;
    int n, m;
    int cnt[N];
    
    int devide(int h)
    {
        int sum = 0;
        for(int i = 1; i <= n; i++)
            if(cnt[i])
                sum += (cnt[i]+h-1)/h; //上取整
        return sum<=m;
    }
    int main()
    {
        cin >> n >> m;
        int x;
        for(int i = 0; i < n; i ++)
        {
            scanf("%d", &x);
            cnt[x]++;
        }
        
        int l = 1, r = n;
        while(l<r)
        {
            int mid = (l + r)>>1;
            if(devide(mid)) r = mid;
            else l = mid + 1;
        }
        
        if(devide(r)) cout << r;
        else cout << "-1";
        return 0;
    }
    F过桥https://ac.nowcoder.com/acm/contest/11217/F

     bfs + 邻接表

    从终点反向奔赴,利用bfs更新最短距离

    #include<iostream>
    #include<cstring>
    using namespace std;
    
    const int N = 2010, M = N * N << 1;
    int n, a[N];
    int h[N],e[M],ne[M],idx;
    int step[N];
    int q[M];
    
    void add(int a, int b){
        e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
    }
    
    int bfs(int u)
    {
        memset(step, -1, sizeof step);
        
        int front = -1, rear = -1;
        step[u] = 0;
        q[++rear] = u;
        
        while(front<=rear)
        {
            int t = q[++front];
            for(int i = h[t]; i != -1; i = ne[i]){
                int j = e[i];
                if(step[j] == -1){
                    q[++rear] = j;
                    step[j] = step[t]+1;
                }
            }
        }
        return step[1];
    }
    int main()
    {
        cin >> n;
        
        memset(h, -1, sizeof h);
        for(int i = 1; i <= n; i ++)
        {
            scanf("%d", &a[i]);
            //双向奔赴,为正为负都看作是反向可达
            if(a[i]>0){
                int r = min(n, a[i]+i);
                for(int j = i+1; j <= r; j++) add(j,i);
            }else{
                int l = max(1, a[i]+i);
                for(int j = 1; j <= l; j++) add(j,i);
            }
        }
        cout << bfs(n);
        return 0;
    }

    G空调遥控https://ac.nowcoder.com/acm/contest/11217/G

    前缀和, 注意控制区间别越界

    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int N = 1e6+10;
    int cnt[N],s[N];
    int main()
    {
        int n,p,res=0;
        cin>>n>>p;
        
        int x;
        for(int i = 0 ; i < n; i++){
            scanf("%d",&x);
            cnt[x] ++;
        }
        for(int i = 1 ; i <= n; i++){
            cnt[i] += cnt[i-1];
        }
        for(int i = 1 ; i <= n; i++){
            int t = cnt[min(n, i+p)] - cnt[max(0,i-p-1)];//求区间和
            if(res < t) res = t;
        }
        cout << res;
    }

    I体操队形https://ac.nowcoder.com/acm/contest/11217/I

    求top序的数量, n≤10直接爆搜 

    #include<iostream>
    using namespace std;
    
    const int N = 11;
    int n, res;
    int a[N], in[N], st[N];
    
    void dfsTop(int u)
    {
        if(u == n){
            res ++;
            return ;
        }
        
        for(int i = 1; i <= n; i ++)
        {
            if(!st[i] && !in[i])//入度为零且未访问
            {
                if(i!=a[i])
                    in[a[i]]--;
                st[i] = 1;
                dfsTop(u+1);
                st[i] = 0;
                if(i!=a[i])
                    in[a[i]]++;
            }
        }
    }
    int main()
    {
        cin >> n;
        for(int i = 1; i <= n; i++)
        {
            cin >> a[i];
            if(i!=a[i]) in[a[i]]++;
        }
        dfsTop(1);
        cout << res;
        return 0;
    }

  • 相关阅读:
    LightOJ 1132 Summing up Powers(矩阵快速幂)
    hdu 3804 Query on a tree (树链剖分+线段树)
    LightOJ 1052 String Growth && uva 12045 Fun with Strings (矩阵快速幂)
    uva 12304 2D Geometry 110 in 1! (Geometry)
    LA 3263 That Nice Euler Circuit (2D Geometry)
    2013 SCAUCPC Summary
    poj 3321 Apple Tree (Binary Index Tree)
    uva 11796 Dog Distance (几何+模拟)
    uva 11178 Morley's Theorem (2D Geometry)
    动手动脑
  • 原文地址:https://www.cnblogs.com/Knight02/p/15799043.html
Copyright © 2020-2023  润新知