“蔚来杯“2022牛客暑期多校训练营4-N、K、D、H

N-Particle Arts

题面

在这里插入图片描述

输入样例

5
1 2 3 4 5

输出样例

54/5

题意

给定一个数组 n n n,数组中的任意两个元素 a , b a,b a,b 都可能产生碰撞,并形成两个新的元素 a & b a\&b a&b a ∣ b a|b ab ,而原先的元素 a , b a,b a,b 将消失。求若干次后该数组趋近的稳定方差是多少。

容易得到样例中最后得到的数组应为: 0   0   1   7   7 0\ 0\ 1\ 7\ 7 0 0 1 7 7 ,即对于原数组中所有元素各位上的 1 1 1,都优先全部分配给稳定数组中的同一位。

采用方差公式: n ∗ p s u m − s u m ∗ s u m n ∗ n \frac{n*psum-sum*sum}{n*n} nnnpsumsumsum

其中 n n n 为样本数, s u m = ∑ i = 1 n x i sum=\sum_{i=1}^{n}{x_i} sum=i=1nxi p s u m = ∑ i = 1 n x i 2 psum=\sum_{i=1}^{n}{x_i^2} psum=i=1nxi2

参考代码

#include <bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int N = 1e5 + 10;

int a[N], b[N], cnt[N];

void solve() {
    int n;
    cin >> n;
    int sum = 0;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        sum += a[i];
        for (int j = 0; j < 15; j++) {
            if ((a[i] >> j) & 1) {
                cnt[j]++;
            }
        }
    }

    for (int i = n; i >= 1; i--) {
        for (int j = 0; j < 15; j++) {
            if (cnt[j]) {
                b[i] += (1 << j);
                cnt[j]--;
            }
        }
    }
    int ans = 0;
    int psum = 0;
    for (int i = 1; i <= n; i++) {
        psum += b[i] * b[i];
    }
    ans = n * psum - sum * sum;
    int ans2 = n * n;
    if (ans == 0) {
        cout << "0/1" << endl;
        return;
    }
    int gg = __gcd(ans, ans2);
    ans /= gg, ans2 /= gg;
    cout << ans << "/" << ans2 << endl;
}

signed main() {
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int T = 1;
    // cin >> T;
    while (T--)
        solve();
    return 0;
}

K-NIO’s Sword

题面

在这里插入图片描述

输入样例

4

输出样例

4

样例解释

在这里插入图片描述

题意

初始时攻击力为 0 0 0,每次可以任意在攻击力之后添加一个数字,仅有在攻击力模 n n n i i i 同余时才能够击杀第 i i i 个敌人,问需要的最少升级次数。

暴力跑结论公式即可,注意特判 n = 1 n=1 n=1 时的情况。

警惕开场 10 10 10 分钟暴力猜结论输入什么输出什么,喜提罚时。

参考代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 10;

void solve() {
    int n;
    cin >> n;
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        int now = 1;
        for (int j = 0; j <= N; j++) {
            if (((i - (i - 1) * (now % n) % n) % n + n) % n < now) {
                ans += j;
                break;
            }
            now = now * 10;
        }
    }
    cout << ans << endl;
}

signed main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T = 1;
//     cin >> T;
    while (T--)
        solve();
    return 0;
}

D-Jobs (Easy Version)

本题感恩由 xia0ji 在赛时解决出来的,翻译+思路都很清晰,贴个题解链接推荐移步!

H-Wall Builder II

题面

在这里插入图片描述

输入样例

4
1
2
3
4

输出样例

4
0 0 1 1
8
0 1 1 2
1 1 2 2
0 0 2 1
14
2 1 3 2
3 1 4 2
4 1 5 2
3 0 5 1
0 1 2 2
0 0 3 1
18
4 0 5 1
2 3 3 4
3 3 4 4
4 3 5 4
3 1 5 2
3 2 5 3
0 3 2 4
0 1 3 2
0 2 3 3
0 0 4 1

题意

当前拥有 n n n 块长度为 1 1 1 n − 1 n-1 n1 块长度为 2 2 2 … … 2 2 2 块长度为 n − 1 n-1 n1 1 1 1 块长度为 n n n 的砖头,且所有的砖头高度为 1 1 1 。要求利用所有砖头铺成一个矩形(不能够竖放),求该矩形的最小周长及对应的摆放状态。

利用公式 n ∗ ( n + 1 ) ∗ ( n + 2 ) 6 \frac{n * (n + 1) * (n + 2)}{6} 6n(n+1)(n+2) 得到面积,当面积确定时,最接近 s q r t ( s ) sqrt(s) sqrt(s) 的长宽为让周长最小的方案。将较长的边作为底边,按照长度从大到小枚举所有砖头的插入方案,倒序输出即可。

参考代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 10;
int len[N];

struct node {
    int x1, y1, x2, y2;
};

vector<node> ans;

void solve() {
    int n;
    cin >> n;
    int s = n * (n + 1) * (n + 2) / 6;
    ans.clear();
    if (n == 1) {
        cout << "4" << endl << "0 0 1 1" << endl;
        return;
    }

    int a = 0, b = 0;
    for (b = sqrt(s); b <= s; b++) {
        a = s / b;
        if (s % b == 0)
            break;
    }

    cout << 2 * (a + b) << endl;
    for (int i = 0; i <= b; i++) {
        len[i] = 0;
    }
    if (a > b)
        swap(a, b);

    for (int i = n; i >= 1; i--) {                //当前块的长度
        for (int j = 1; j <= n - i + 1; j++) {    //块数
            for (int lie = 1; lie <= a; lie++) {  //枚举每列
                if (b - len[lie] >= i) {
                    ans.push_back({len[lie], lie - 1, len[lie] + i, lie});
                    len[lie] += i;
                    break;
                }
            }
        }
    }

    for (int i = ans.size() - 1; i >= 0; i--) {
        cout << ans[i].x1 << " " << ans[i].y1 << " " << ans[i].x2 << " "
             << ans[i].y2 << endl;
    }
}

signed main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T = 1;
    cin >> T;
    while (T--)
        solve();
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值