• [牛客小\白月赛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;
    }

  • 相关阅读:
    Python开发之路
    openstack系列阅读目录
    linux基础
    PEP8规范
    我真的还是18岁的那个我
    为什么很多IT公司不喜欢进过培训机构的人呢?
    GRE与VXLAN
    VLAN模式
    网络虚拟化基础一:linux名称空间Namespaces
    四:OVS+GRE之网络节点
  • 原文地址:https://www.cnblogs.com/Knight02/p/15799043.html
Copyright © 2020-2023  润新知