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

原文地址:https://www.cnblogs.com/Knight02/p/15799043.html