Codeforces Round #375 (Div. 2) Polycarp at the Radio 优先队列模拟题 + 贪心
http://codeforces.com/contest/723/problem/C
题目是给出一个序列
a[i]表示第i个歌曲是第a[i]个人演唱,现在选出前m个人,记b[j]表示第j个人演唱歌曲的数量,
现在你可以改变a[]这个数组,使得前m个人的演唱歌曲的数量的最小值最大。
很明显对于前m个人,每个人唱了多少首是很容易统计出来的,只需要对<=m的人进行统计即可,不用统计>m的,这样的话数组只需开到2000即可。
对于后面的人,可以改变,优先改变前m个人中演唱歌曲最小的那个,这个可以用优先队列维护。
然后如果前m个人本来分配不均匀,那么最小值的最大值得不到最大化。
要对前m个人均匀一下,这个我用了两个优先队列去做,因为思路就是把最大的分一次给最小的,这样的最优的。
hack点:注意到ans最多也只是n / m。就相当于把n分成m分,如果前m个人的答案已经是n / m,后面的人就不需要变化的,不然的话改变数量变大了,会错误。好像wa7就是这个坑。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
int n, m;
const int maxn = + ;
int book[maxn];
int a[maxn];
struct node {
int num;
int id;
bool operator < (const struct node &rhs) const {
return num > rhs.num;
}
node(int aa, int bb) : num(aa), id(bb) {}
};
struct GGnode {
int num;
int id;
bool operator < (const struct GGnode &rhs) const {
return num < rhs.num;
}
GGnode(int aa, int bb) : num(aa), id(bb) {}
};
priority_queue<struct node>que;
priority_queue<struct GGnode>GGque;
vector<int>pos[maxn];
void work() {
scanf("%d%d", &n, &m);
for (int i = ; i <= n; ++i) {
scanf("%d", &a[i]);
if (a[i] <= m) {
book[a[i]]++;
}
}
for (int i = ; i <= m; ++i) {
que.push(node(book[i], i));
}
int tochange = ;
int get = n / m;
for (int i = ; i <= n; ++i) {
if (a[i] <= m) continue;
struct node t = que.top();
if (t.num == get) break;
que.pop();
a[i] = t.id;
t.num++;
que.push(t);
tochange++;
}
memset(book, , sizeof book);
while (!que.empty()) {
struct node t = que.top();
que.pop();
book[t.id] = t.num;
}
int all = ;
int ans = inf;
for (int i = ; i <= m; ++i) {
ans = min(ans, book[i]);
all += book[i];
que.push(node(book[i], i));
GGque.push(GGnode(book[i], i));
}
for (int i = ; i <= n; ++i) {
if (a[i] <= m) {
pos[a[i]].push_back(i);
}
}
int gold = all / m;
if (ans != gold) {
while (true) {
struct node tt = que.top();
que.pop();
struct GGnode GGtt = GGque.top();
GGque.pop();
if (book[tt.id] == gold) break; book[tt.id]++;
book[GGtt.id]--;
int tpos = pos[GGtt.id].back();
pos[GGtt.id].pop_back();
a[tpos] = tt.id; tt.num = book[tt.id];
GGtt.num = book[GGtt.id]; que.push(tt);
GGque.push(GGtt);
tochange++;
}
}
ans = gold;
cout << ans << " " << tochange << endl;
for (int i = ; i <= n; ++i) {
printf("%d ", a[i]);
}
return;
} int main() {
#ifdef local
freopen("data.txt","r",stdin);
#endif
work();
return ;
}
感觉写的有点麻烦,
所以重写了一次。
考虑到它一定要使得b[j]数组中的最小值最大,而这个最大值,必然是n / m的。所以,直接把1---m中数量小于n / m的统计起来,用其他去变即可。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = + ;
int a[maxn];
int book[maxn];
set<int>pos;
void work() {
int n, m;
scanf("%d%d", &n, &m);
int gold = n / m;
for (int i = ; i <= n; ++i) {
scanf("%d", &a[i]);
if (a[i] <= m) {
book[a[i]]++;
}
}
for (int i = ; i <= n; ++i) {
if (a[i] <= m && book[a[i]] < gold) {
pos.insert(a[i]);
}
}
for (int i = ; i <= m; ++i) {
if (book[i] < gold) pos.insert(i);
}
// printf("ff");
int toChange = ;
set<int> :: iterator it = pos.begin();
if (it != pos.end()) { //如果需要调整
int val = *it;
for (int i = ; i <= n; ++i) {
if (a[i] > m) {
book[val]++;
a[i] = val;
toChange++;
} else {
if (pos.find(a[i]) != pos.end()) continue;
if (book[a[i]] == gold) continue;
book[a[i]]--;
book[val]++;
a[i] = val;
toChange++;
}
if (book[val] == gold) {
it++;
if (it == pos.end()) break;
val = *it;
}
}
}
printf("%d %d\n", gold, toChange);
for (int i = ; i <= n; ++i) {
printf("%d ", a[i]);
}
return ;
} int main() {
#ifdef local
freopen("data.txt","r",stdin);
#endif
work();
return ;
}
Codeforces Round #375 (Div. 2) Polycarp at the Radio 优先队列模拟题 + 贪心的更多相关文章
- Codeforces Round #375 (Div. 2)【A,B【模拟】,D【DFS】】
PS_B:阿洗吧!B题卧槽数组开了250... PS_D:D题主要挂在了50*50口算得了250,数组开小,然后一开始还错了.= =哎,以后对于数据范围还是注意一点: 卧槽,这场可真二百五了... A ...
- Codeforces Round #234 (Div. 2) A. Inna and Choose Options 模拟题
A. Inna and Choose Options time limit per test 1 second memory limit per test 256 megabytes input st ...
- Codeforces Round #368 (Div. 2) A. Brain's Photos (水题)
Brain's Photos 题目链接: http://codeforces.com/contest/707/problem/A Description Small, but very brave, ...
- Codeforces Round #375 (Div. 2) C. Polycarp at the Radio 贪心
C. Polycarp at the Radio time limit per test 2 seconds memory limit per test 256 megabytes input sta ...
- Codeforces Round #375 (Div. 2)
A. The New Year: Meeting Friends 水 #include <set> #include <map> #include <stack> ...
- Codeforces Round #375 (Div. 2) A B C 水 模拟 贪心
A. The New Year: Meeting Friends time limit per test 1 second memory limit per test 256 megabytes in ...
- Codeforces Round #375 (Div. 2) ABCDE
A - The New Year: Meeting Friends 水 #include<iostream> #include<algorithm> using namespa ...
- Codeforces Round #281 (Div. 2) A. Vasya and Football 模拟
A. Vasya and Football 题目连接: http://codeforces.com/contest/493/problem/A Description Vasya has starte ...
- Codeforces Round #375 (Div. 2) - D
题目链接:http://codeforces.com/contest/723/problem/D 题意:给定n*m小大的字符矩阵.'*'表示陆地,'.'表示水域.然后湖的定义是:如果水域完全被陆地包围 ...
随机推荐
- JQUERYUI 框架 http://jqueryui.com/
http://jqueryui.com/
- Linux CentOS安装Azure Cli工具
vim /etc/yum.repos.d/epel.repo [epel] name=epel baseurl=http://mirrors.sohu.com/fedora-epel/6/$basea ...
- UML核心元素--用例
定义:用例定义了一组用例实例,其中每个实例都是系统所执行的一些列操作,这些操作生成特定主角可以观测的值.一个完整的用例定义由参与者.前置条件.场景.后置条件构成. 1.理解用例:用例就是参与者希望通过 ...
- df查看分区使用情况
Linux df命令用于显示目前在Linux系统上的文件系统的磁盘使用情况统计.语法 df [选项]... [FILE]... -a, --all 包含所有的具有 0 Blocks 的文件系统 ...
- Redux API之compose
compose(...functions) 从右到左来组合多个函数. 这是函数式编程中的方法,为了方便,被放到了 Redux 里. 当需要把多个 store 增强器 依次执行的时候,需要用到它. 参数 ...
- BZOJ4085: [Sdoi2015]音质检测
BZOJ4085: [Sdoi2015]音质检测 由于这题太毒了,导致可能会被某些人卡评测,于是成了一道权限题... 本蒟蒻表示没钱氪金... 但是可以去洛谷/Vijos搞搞事... 但是洛谷上只能评 ...
- 【eclipse】Eclipse安装插件支持jQ…
[eclipse]Eclipse安装插件支持jQuery智能提示 最近工作中用到jQuery插件,需要安装eclipse插件才能支持jQuery智能提示,在网上搜索了一下,常用的有三个插件支持jQue ...
- ubuntu中解决/usr/bin/ld: cannot find -lxxx
解决/usr/bin/ld: cannot find -lxxx 在linux环境编译应用程式或lib的source code时常常会出现如下的错误讯息:/usr/bin/ld: cannot fin ...
- 一个web.Config或app.Config自定义段configSections的示例--转
直接用配置文件app.Config或web.Config配置应用系统的运行参数,比自己做一个xml配置文件,简洁方便得多.这两个配置文件不仅有常见的connectionStrings和appSetti ...
- Windows10安装node.js,vue.js以及创建第一个vue.js项目
[工具官网] Node.js : http://nodejs.cn/ 淘宝NPM: https://npm.taobao.org/ 一.安装环境 1.本机系统:Windows 10 Pro(64位)2 ...