20220730牛客暑期多校第四场

Particle Arts(签到题)

题目描述:
空间中有n个粒子,每个粒子都有自己的能量,粒子a与粒子b相碰,他们的值会变成a&b和a|b,所有粒子的能量的方差不会减少,求最终稳定时粒子的方差。

input:
5
1 2 3 4 5

output:
54/5

解:
稳定时,即a&b=a或者b,a|b=b或者a,任何两个粒子都满足这种情况
&和|对操作,其实就是将1与0调换位置。
对于普遍的情况,举例:
111111111
111111110
111111100
111111000
...
000000000
最终稳态如上图
对于一堆数某一个位上全是0或者全是1的情况,其实不管是&还是|这一位上情况都不会改变都是全0或者全1,不用管

#include<iostream>
using namespace std;
#define ll unsigned long long

ll bits[15];//用来存取某个比特位上有多少个1

ll gcd(ll a, ll b) {//辗转相除法求最大公约数
    return b ? (gcd(b, a % b)) : a;
}

int main() {
    int n;
    cin >> n;
    ll c, sum = 0;
    for (int i = 1; i <= n; i++) {
        cin >> c;
        sum += c;
        for (int j = 0; c != 0 && j < 15; j++) {
            if ((c & 1) == 1) {//如果这一位为1,bits[j]++
                bits[j]++;
            }
            c >>= 1;
        }
    }
    ll x = 0;
    for (int i = 1; i <= n; i++) {
        ll temp = 0;
        for (int j = 0; j < 15; j++) {
            if (i <= bits[j]) {//1的分配,i<=bits[j],表示这个数在j比特位上可以分配1
                temp += (1 << j);
            }
        }
        x += temp * temp;
    }
    ll a = n * x - sum * sum;//公差的公式
    ll b = (ll)n * n;
    ll g = gcd(a, b);
    cout << a / g << '/' << b / g;
}

NIO’s Sword

题目描述:
有n个敌人,你有一把剑,初始攻击力为a,a=0,对于2-n个敌人,剑的攻击力必须符合a%n==i%n,才能够将其击杀,并且只能按照顺序击杀,你可以强化你的剑的攻击力,每次强化你的攻击力都可以变成a*10+x(0<=x<=9),求击杀所有敌人并且强化次数最少的值

input:
4

output:
4

解:
设击杀第i-1个人时攻击力为a(i-1),强化了k次能够击杀第i个敌人,所以a(i)=a(i-1)10^k+y。同时模n,有
i%n=((i-1)
10^k+y)%n
这里需要分析一下y的范围,假设每次强化x都取0,那么y=0,假设每次强化x都取9,那么y=10^k-1(等比数列求和),
枚举k的值,并且计算y,如果y满足这个范围,那么就找到了最小的k,处理下一个敌人。

#include<iostream>
#include<cmath>

#define int long long
using namespace std;

signed main() {
    int n;
    cin >> n;
    if (n == 1) {//特判
        cout << 0 << endl;
    }
    int res = 0;
    for (int i = 1; i <= n; i++) {
        for (int k = 1; 1; k++) {//枚举k的值
            int base = (i - 1) * pow(10, k);
            int x = (((i - base) % n) + n) % n;//i-base可能是负数
            if (x < pow(10, k)) {
                res += k;
                break;
            }
        }
    }
    cout << res << endl;
}

Jobs (Easy Version)

题目描述:
有n个公司,每个公司有m份工作,每份工作有三个指标,只有大于这三个指标才能胜任这份工作,给定q个人,求出每个人最多能进几个公司。

解:
将每个公司的工作的三个指标和升序排列,如果这个人的三个指标和小于这个工作,那么后面的工作也无法胜任。

#include<iostream>
#include <random>
#include<algorithm>
using namespace std;

typedef long long ll;
#define int long long

ll mod = 998244353;
ll n, m[100005];
ll seedm[2000005];

struct gongsi {
    ll a, b, c;
    ll sum;
} g[11][100005];

int cmp(gongsi x, gongsi y) {
    return x.sum < y.sum;
}

ll solve(ll x, ll y, ll z) {
    ll sum1 = x + y + z;
    ll res = 0;
    for (int i = 1; i <= n; i++) {
        bool is = 0;
        for (int j = 1; j <= m[i]; j++) {
            if (sum1 < g[i][j].sum) {
                break;
            }
            if (x >= g[i][j].a && y >= g[i][j].b && z >= g[i][j].c) {
                is = 1;
                break;
            }
        }
        if (is) res++;
    }
    return res;
}

signed main() {
    ios::sync_with_stdio(false);
    ll res = 0;
    ll q;
    ll seed;
    cin >> n >> q;
    for (int i = 1; i <= n; i++) {
        cin >> m[i];
        for (int j = 1; j <= m[i]; j++) {
            cin >> g[i][j].a >> g[i][j].b >> g[i][j].c;
            g[i][j].sum = g[i][j].a + g[i][j].b + g[i][j].c;
        }
        sort(g[i] + 1, g[i] + m[i] + 1, cmp);
    }
    cin >> seed;
    seedm[0] = 1;
    ll seedmod = seed % mod;
    for (int i = 1; i < q; i++) {
        seedm[i] = seedm[i - 1] * seedmod % mod;
    }
    std::mt19937 rng(seed);
    std::uniform_int_distribution<> u(1, 400);
    ll lastans = 0;
    for (int i = 1; i <= q; i++) {
        int IQ = (u(rng) ^ lastans) % 400 + 1;  // The IQ of the i-th friend
        int EQ = (u(rng) ^ lastans) % 400 + 1;  // The EQ of the i-th friend
        int AQ = (u(rng) ^ lastans) % 400 + 1;  // The AQ of the i-th friend
        lastans = solve(IQ, EQ, AQ);  // The answer to the i-th friend
        res += lastans * seedm[q - i] % mod;
        res %= mod;
    }
    cout << (res + mod) % mod << endl;

}
#ACM##算法竞赛##菜鸡的求救#
全部评论
签到题是啥意思
1 回复 分享
发布于 2022-08-13 17:41

相关推荐

02-07 12:06
已编辑
华侨大学 测试开发
最近看到很多&nbsp;92&nbsp;的,甚至是硕士,开始往测开赛道卷,说实话有点看不懂。先把话说清楚,大厂里的测开,绝大多数时间干的还是测试的活,只是写点自动化脚本、维护测试平台、接接流水线,真正像开发一样做系统、做架构、做核心平台的测开少得可怜,基本都集中在核心提效组,而且人很少,外面进去的大概率轮不到你,我想真正干过人都清楚。很多人被洗脑了,以为测开也是开,和后端差不多,只是更简单、更轻松、还高薪。现实情况是,测开和开发的职业路径完全不一样。开发的核心是业务和系统能力,测开的核心是稳定性和覆盖率,前者是往上走,后者天花板非常明显。你可以见到很多开发转测开,但你很少见到干了几年测开还能顺利转回开发的。更现实一点说,92&nbsp;的高学历如果拿来做测开,大部分时间就是在做重复性很强的杂活,这种工作对个人能力的放大效应非常弱。三年下来,你和一个双非的,甚至本科的测开差距不会太大,但你和同龄的后端、平台开发差距会非常明显。这不是努不努力的问题,是赛道问题。所谓测开简单高薪,本质上是把极少数核心测开的上限,当成了整个岗位的常态来宣传。那些工资高、技术强的测开,本身就是开发水平,只是挂了个测开的名。普通人进去,99%&nbsp;做的都是项目兜底型工作,而不是你想象中的平台开发。测开不是不能做,但它绝对不是开发的平替,也不是性价比最优解。如果你是真的不想做开发,追求稳定,那测开没问题。但如果你只是觉得测开比后端容易,还能进大厂,那我劝你冷静一点,这只是在用短期安全感换长期天花板。有92的学历,如果你连测开这些重复性工作都能心甘情愿接受,那你把时间精力用在真正的开发、系统、业务深度上,回报大概率比卷测开要高得多。想清楚再下场,别被岗位名和话术带偏了,就算去个前端客户端也是随便占坑的,测开是一个坑位很少赛道,反而大面积学历下放,不用想也能知道会是什么结果,我想各位在JAVA那里已经看到了
小浪_Coding:工作只是谋生的手段 而不是相互比较和歧视
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务