window.cnblogsConfig = {//可以放多张照片,应该是在每一个博文上面的图片,如果是多张的话,那么就随机换的。 homeTopImg: [ "https://cdn.luogu.com.cn/upload/image_hosting/clcd8ydf.png", "https://cdn.luogu.com.cn/upload/image_hosting/clcd8ydf.png" ], }

CF234E解题报告

CF234E 解题报告

题意

题目传送门

给你 \(n\) 个球队,和四个作为随机数生成器的变量,再给出每个球队的名称和积分,让你通过某种随机数来进行分组。

分组方法:将 \(n\) 个球队分到 \(n/4\) 个盒子中,求出随机数 \(x=(x \times a + b)\bmod c\),再抽取盒子中剩余球队编号为 \(k \bmod s\) 的球队装进大组中,其中 \(k\) 为随机数,\(s\) 为盒子中剩余球队的数量。

抽象的题意理解完成之后,很容易看出来这是一道大模拟,稍微调一下代码就可以了。

分析

可以先将球队的积分从大到小排序,然后按照题意放进盒子中,然后将盒子中的元素通过随机数取出对应的元素放进大组中。

其中将积分从大到小的操作可以使用 vector 进行优化,通过 sortreverse 可以实现,在进行从盒子中弹出的时候也可以用 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;
}
posted @ 2023-12-02 14:22  CCF_IOI  阅读(33)  评论(0)    收藏  举报