Codeforces Round #844:C. Equal Frequencies
一、来源:Problem - C - Codeforces
二、题面

三、思路
先考虑一个子问题模型:我们现在有用\(m_1\)种随机字母组成的n个数,各字母个数未定,现在需要使这n个数变为\(m_2\)种类,平均每个种类为blance=n/\(m_2\)个数,问如何求得最小的改变数
显然,只能由多的数向少的数改变,为此我们先尝试求出所有所有字母出现的次数并对其进行降序排序得到
vector<pair<int,int>> v;\\pair的first为字母小标(由0开始),second为字母出现的个数我们考虑转换的过程,其实就是较高位-1,较低位+1的过程.
- 尝试只找需要减去的位,初一看我们在前面高位用
v[i].second减去blance直到v[i].second<=blance即可,然而事实上这情况讨论过的前提是\(m_1<m_2\);当\(m_1>m_2\),以数列9,3,3,3,2为例,我么将其转为为5,5,5,5,,最前面的9需要减去,后面的2也需要减去,这就比较复杂了 - 尝试只找需要增加的位:根据上面错误的经验,我们可以得到需要增加的部分都是在m2之前的,且都可以使用表达式
ans+=blance-v[i].second.经代码验证可以得到复合题意的解
- 尝试只找需要减去的位,初一看我们在前面高位用
code
#include<bits/stdc++.h> using namespace std; bool cmp(const pair<int,int> a,pair<int,int> b){
return a.second > b.second;
} char toChar(int offset){
return 'a'+offset;
} int toInt(char c){
return c-'a';
} int main(){
int t;
cin >> t;
while(t--){
int n,m2; //n个数转换为m种,每种n/m个
char str[100];
cin >> n >> m2;
cin >> str;
map<int,int> mp;
for(int i=0;i<26;i++){ //需初始化
mp[i]=0;
}
int m1=0;
for(int i=0;i<n;i++){
if(++mp[toInt(str[i])]==1){
m1++;
}
}
vector<pair<int,int>> v(mp.begin(),mp.end());
sort(v.begin(),v.end(),cmp);
int ans=0,blance=n/m2;
for(int i=0;i<m2;i++){
if(v[i].second<blance){
ans+=blance-v[i].second;
}
}
cout << ans << endl;
}
return 0;
}
注:该问题模型其实还可以简化为:n个和为sum的数,每次加一减一,通过加减操作转化为m个相同的数,每个数为sum/m,所需要的最少加减次数
将问题分解:本题注意到小写字母是可以遍历的,我们可以遍历26种可能的情况求得变化最小的一次解的值,然后再对字符串进行变换
- 遍历26种可能并求得变化最小的一个解
- 模拟求变换即可(这里的代码属于是暴力了)
补充:对于
toChar,toInt,最好还是封装为函数
四、代码
#include <bits/stdc++.h>
#define eleType int
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
//字母遍历
//设字母总数为n,平等值为m => n<26*m且n%m==0
const int N=1e5+10;
char arr[N];
map<int,int> mp;
bool cmp(const pair<int,int> a,pair<int,int> b){
return a.second > b.second;
}
char toChar(int offset){
return 'a'+offset;
}
int toInt(char c){
return c-'a';
}
int main(){
int t;
cin >> t;
while(t--){
eleType n;
cin >> n >> arr;
for(int i=0;i<26;i++){ //需初始化
mp[i]=0;
}
int m1=0;
for(int i=0;i<n;i++){
if(mp[toInt(arr[i])]++==0){
m1++;
}
}
vector<pair<int,int>> v(mp.begin(),mp.end());
sort(v.begin(),v.end(),cmp);
eleType ans=INF,m2=1,blance;
for(int i=1;i<=26;i++){
if(n%i==0){ //i是种类,不是个数,不需要保证26*i>=n
// cout << "i:" << i << endl;
eleType temp=0,now=0;
blance=n/i;
for(int j=0;j<i;j++){
//cout << "mp[" << j << "]:" << mp[j] << endl;
if(v[j].second<blance){
temp+=blance-v[j].second;
}
}
// cout << temp << endl;
if(temp<ans){
ans=temp;
m2=i;
}
// cout << "i:" << i << " temp:" << temp << endl;
}
}
blance = n/m2;
eleType next=0;
for(int i=0;i<v.size();i++){
if(v[i].second<blance){
next=i;
break;
}
}
// cout << m2 << endl;
for(int i=0;i<n;i++){
eleType now;
for(int j=0;j<v.size();j++){
if(arr[i] == toChar(v[j].first)){ //易错漏,转换应封装为函数
now=j; //排序后的位置
}
}
if(v[now].second>blance||now>=m2){ //多余数,后者所在的种类位次超过m2
//在前面或后面
v[now].second--;
// cout << "v[next].first:" << v[next].first << endl;
arr[i]=toChar(v[next].first);
if(++v[next].second==blance){
next++;
}
}
}
cout << ans << endl;
cout << arr << endl;
}
return 0;
}
Codeforces Round #844:C. Equal Frequencies的更多相关文章
- Codeforces Round #844 (Div.1 + Div.2) CF 1782 A~F 题解
点我看题 A. Parallel Projection 我们其实是要在这个矩形的边界上找一个点(x,y),使得(a,b)到(x,y)的曼哈顿距离和(f,g)到(x,y)的曼哈顿距离之和最小,求出最小值 ...
- Codeforces Round #844 (Div. 1 + Div. 2, based on VK Cup 2022 - Elimination Round) A-D
比赛链接 A 题意 设计一条线路要贴着6个墙面走,从 \((a,b)\) 到 \((f,g)\) ,线路长度最短. 题解 知识点:模拟. 分类取最短即可. 时间复杂度 \(O(1)\) 空间复杂度 \ ...
- cf之路,1,Codeforces Round #345 (Div. 2)
cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅..... ...
- Codeforces Round #262 (Div. 2) 1003
Codeforces Round #262 (Div. 2) 1003 C. Present time limit per test 2 seconds memory limit per test 2 ...
- Codeforces Round #284 (Div. 2)A B C 模拟 数学
A. Watching a movie time limit per test 1 second memory limit per test 256 megabytes input standard ...
- Codeforces Round #270 1003
Codeforces Round #270 1003 C. Design Tutorial: Make It Nondeterministic time limit per test 2 second ...
- Codeforces Round #270 1002
Codeforces Round #270 1002 B. Design Tutorial: Learn from Life time limit per test 1 second memory l ...
- Codeforces Round #285 (Div. 2) A B C 模拟 stl 拓扑排序
A. Contest time limit per test 1 second memory limit per test 256 megabytes input standard input out ...
- Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset (0/1-Trie树)
Vasiliy's Multiset 题目链接: http://codeforces.com/contest/706/problem/D Description Author has gone out ...
- Codeforces Round #367 (Div. 2) C. Hard problem(DP)
Hard problem 题目链接: http://codeforces.com/contest/706/problem/C Description Vasiliy is fond of solvin ...
随机推荐
- hadoop-3.0.0-cdh6.3.2源码编译实践
1.编译过程 参考:https://blog.mygallop.cn/2020/10/centos/hadoop-cdh6-compile/ 2.问题记录 CDH6.3.2 Hadoop源码位置发生变 ...
- vuecli 自动转换小文件为 base64 格式,如何关闭?
1. 问题 最近在写 vue 项目时,发现稍微小一点的静态资源,例如字体文件, 图片都被自动转换为 base64 格式了. 在网上搜索时基本都是去配置 url-loader ,配置后提示:Can't ...
- Python学习之Pytorch
一.如何查看本机是否安装了Pytorch 在Python环境中查看是否安装了PyTorch可以通过几个简单的步骤来完成.这里有一些方法: 使用Python命令行: 打开你的命令行工具(比如Termin ...
- 2023年多校联训NOIP层测试2
2023年多校联训NOIP层测试2 爆零了 T1 HDU 4786 Fibonacci Tree \(0pts\) @wangyunbiao: 不可以,总司令 我:不,可以,总司令 @wangyunb ...
- Java设计模式-命令模式Command
介绍 命令模式(Command Pattern):在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收 者是谁,也不知道被请求的操作是哪个, 我们只需在程序运行时指定具体的请求接收者即 ...
- Doris Fe在Mac上搭建开发环境踩坑记录
1. 拉取代码到本地 git clone https://github.com/apache/doris.git 2. 参考Doris的文档,但别全信(信了你就上当了) 参考第一篇 https://d ...
- 内置方法,序列化模块pickle和json---day15
1.内置方法 ads 绝对值函数 val = -16 res = abs(val) print(res) #16 round 四舍五入(n.5 n为偶数则舍去,n.5 n为奇数 则进一) 奇进偶不进 ...
- 【LeetCode链表#10】删除链表中倒数第n个节点(双指针)
删除链表倒数第N个节点 力扣题目链接(opens new window) 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点. 进阶:你能尝试使用一趟扫描实现吗? 示例 1: 输入:he ...
- 启动Study.BlazorOne项目
由于Study.Trade模块的Blazor是基于国内著名的BootstrapBlazor组件,因此Study.BlazorOne项目也必须添加对BootstrapBlazor的支持. # 1.去Bo ...
- MySQL 数据库死锁排查
死锁排查方法 查看进程状态 show processlist; 查看行锁的状态 show status like 'InnoDB_row_lock%'; 查询是否有死锁 show engine inn ...