牛客小白月赛42 A-E题解

发布于 2021-12-20  1.37k 次阅读


内容纲要

A 冰狱寒岚

签到

代码:

#include<bits/stdc++.h>
using namespace std;

int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        if(n < 1024){
            printf("%d ", n);
        } else {
            if(n % 2048 < 1024){
                printf("%d ", n % 1024);
            } else {
                printf("%d ", n % 1024 - 1024);
            }
        }
    }
    return 0;
}

B 光之屏障

大意:

给你两个整数 x 和 y,让你求一个整数 z,满足 x≤z≤y且 z 是 2的方幂。

题解:

筛出所有2的次方比较

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
long long nums[1000000];
int ant = 1;

void f(){
    long long ans = 1;
    while(ans < 10000000000){
        nums[ant] = ans;
        ans= ans*2;
        ant++;
    }
}

int main(){
    f();
    int t;
    cin>>t;
    while(t--){
        int x,y;
        scanf("%d%d", &x, &y);
        for(int i = 1; i < ant; i++){
            if(nums[i] > y || nums[i] > 1000000000){
                printf("-1\n");
                break;
            }
            if(nums[i] >= x){
                printf("%lld\n", nums[i]);
                break;
            }
        }
    }
    return 0;
}

C 寒潭烟光

大意:

给出一个数组的前缀和的平均数和一个数字

要求求出将这个数字加到这个数组的最前面后的前缀和平均数

题解:

加一个数在前面前缀和求和就会多n+1个这个数,然后加上原来的和再除以n+1就行了

代码:

#include<bits/stdc++.h>
using namespace std;

int main(){
    int t;
    cin>>t;
    while(t--){
        long long n,f,x;
        scanf("%lld%lld%lld", &n, &f, &x);
        long long ans = ((x * (n + 1)) + (n * f)) / (n + 1);
        printf("%lld\n", ans);
    }
}

D 金蛇狂舞

题目大意:

使用 上取整、下取整、阶乘、算术平方根 四种运算,完成对一个数字的变换。

题解:

直接搜索明显超时,看到数据范围很小,遂考虑打表。

代码:

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;

int ans;
int nums[7][7] = {0, -1, -1, -1, -1, -1, -1, 1, 0, -1, -1, -1, -1, -1, 1, 1, 0, 7, 4, 1, -1, 2, 1, 3, 0, 2, 4, -1, 2, 1, 1, 3, 0, 2, 6, 2, 1, 1, 6, 3, 0, -1, 2, 1, 1, 7, 5, 2, 0};

int ss(int n) {
    int x = 1;
    for (int i = 1; i <= n; ++i) {
        x *= i;
    }
    return x;
}

void dfs(int n, int begin, int end, int to) {
    if (n == to) {
        ans = min(begin, ans);
        return;
    }
    if (begin >= end) {
        return;
    }
    dfs(ceil(sqrt(n)), begin + 1, end, to);
    dfs(ss(n), begin + 1, end, to);
    dfs(floor(sqrt(n)), begin + 1, end, to);
    return;
}

int main() {
    int t;
    cin >> t;
    while (t--) {
        int x, y;
        cin >> x >> y;
        printf("%d\n", nums[x - 1][y - 1]);
    }
//  }
//  freopen("1.out", "w", stdout);
//  for (int i = 1; i <= 7; i++) {
//      for (int j = 1; j <= 7; j++) {
//          ans = INF;
//          dfs(i, 0, 7, j);
//          if (ans == INF) {
//              printf("-1\n");
//          } else {
//              printf("%d\n", ans);
//          }
//      }
//  }
//  fclose(stdout);
}

E 暗灭侵蚀

大意:

有 3 个跳跳棋,坐标分别为 abc

每个棋子都可以以 最右侧 的棋子为中点跳跃,若棋子 x 以棋子 y 为中点跳跃,到达的位置为 2yx

求最少通过多少次操作,能使得至少一个棋子坐标≥N

题解:

排序更新就得了

代码:

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
int nums[4];

int main() {
    int t;
    cin>>t;
    while(t--){
        int n;
        long long ans = 0;
        scanf("%d%d%d%d", &nums[1], &nums[2], &nums[3], &n);
        sort(nums + 1, nums + 4);
        while(nums[3] < n){
            nums[1] = (2 * nums[3]) - nums[1];
            ans++;
            sort(nums + 1, nums + 4);
        }
        printf("%lld\n", ans);
    }
}

不爱嘉然小姐十年了。十年里,爱过的每个人都像她。