CF234E解题报告
CF234E 解题报告
题意
给你 \(n\) 个球队,和四个作为随机数生成器的变量,再给出每个球队的名称和积分,让你通过某种随机数来进行分组。
分组方法:将 \(n\) 个球队分到 \(n/4\) 个盒子中,求出随机数 \(x=(x \times a + b)\bmod c\),再抽取盒子中剩余球队编号为 \(k \bmod s\) 的球队装进大组中,其中 \(k\) 为随机数,\(s\) 为盒子中剩余球队的数量。
抽象的题意理解完成之后,很容易看出来这是一道大模拟,稍微调一下代码就可以了。
分析
可以先将球队的积分从大到小排序,然后按照题意放进盒子中,然后将盒子中的元素通过随机数取出对应的元素放进大组中。
其中将积分从大到小的操作可以使用 vector
进行优化,通过 sort
和 reverse
可以实现,在进行从盒子中弹出的时候也可以用 erase
操作解决,优化了数组挪动的时间复杂度。
还有,这个题面好像没有说,原站上说了,要用文件读写。
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, x, a, b, c;
pair<int, string> v[105];
vector<pair<int, string>> w[5];
signed main(){
freopen("input.txt", "r", stdin);//文件读写
freopen("output.txt", "w", stdout);
cin >> n >> x >> a >> b >> c;
for (int i = 0; i < n; i++) cin >> v[i].second >> v[i].first;
int m = n / 4;
sort(v, v + n);
reverse(v, v + n);//通过reverse实现从小到大变成从大到小
for (int i = 0; i < n; i++) w[i / m].push_back(v[i]);//装进盒子里
for (int i = 0; i < m; i++){
printf("Group %c:\n", i + 'A');
for (int j = 0; j < 4; j++){
x = (x * a + b) % c;
int pos = x % (m - i);//随机数
printf("%s\n", w[j][pos].second.c_str());
w[j].erase(w[j].begin() + pos);//从盒子里拿出来,放进大组中
}
}
return 0;
}