Codeforces Round #377 (Div. 2) E. Sockets
http://codeforces.com/contest/732/problem/E
题目说得很清楚,每个电脑去插一个插座,然后要刚好的,电脑的power和sockets的值相同才行。
如果不同,还有一个操作,就是在sockets中插东西,使得sockets的值变成val / 2 + (val & 1)
要求输出最多插多少个电脑和最小的代价。
开始的时候,就有一个暴力的思路了,
就是,用优先队列维护sockets,每次弹出插了最小adapters的一个sockets,然后就是电脑那里找,有得插就插。
找的时候,明显可以把电脑的val排序,然后二分加速。但是有一个问题,就是电脑的val可能是相同的。然后查找完后,
又要标记它用了,后来二分的时候就很麻烦,如果删除,复杂度也高。
同时因为也要记录电脑的id(因为要输出方案),这样用set来保存的话,我刚开始不懂set.lower_bound中怎么二分其中一个值,
因为我只需要二分val。其实就把整个结构体二分就行了,会根据你的重载运算符来二分的,优先二分val,再二分id。
而且set的删除也可以Logn,所以这题就相当于是STL的题了。
set删除迭代器,处理下边界就好,it == ss.end()的时候、
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = + ;
struct nodeComputer {
int val, id;
bool operator < (const struct nodeComputer &rhs) const {
if (val != rhs.val) return val < rhs.val;
else return id < rhs.id;
}
nodeComputer(int a, int b) : val(a), id(b) {}
};
struct nodeSocket {
int val, id, cnt;
bool operator < (const struct nodeSocket &rhs) const {
if (cnt != rhs.cnt) return cnt > rhs.cnt;
else if (val != rhs.val) return val > rhs.val;
else return id > rhs.id;
}
nodeSocket(int a, int b, int c) : val(a), id(b), cnt(c) {}
};
set<struct nodeComputer>ss;
priority_queue<struct nodeSocket>que;
int ansSocker[maxn];
int ansComputer[maxn];
void work() {
int n, m;
scanf("%d%d", &n, &m);
for (int i = ; i <= n; ++i) {
int val;
scanf("%d", &val);
ss.insert(nodeComputer(val, i));
}
// for (set<struct nodeComputer> :: iterator it = ss.begin(); it != ss.end(); ++it) {
// printf("%d %d\n", it->val, it->id);
// }
// set<struct nodeComputer> :: iterator it = ss.lower_bound(nodeComputer(1, 3));
// printf("%d\n", it == ss.end());
for (int i = ; i <= m; ++i) {
int val;
scanf("%d", &val);
que.push(nodeSocket(val, i, ));
}
int ansc = , ansu = ;
while (!que.empty()) {
struct nodeSocket t = que.top();
que.pop();
set<struct nodeComputer> :: iterator it = ss.lower_bound(nodeComputer(t.val, ));
if (it == ss.end() || it->val != t.val) {
if (t.val == ) continue; //再分解就没意思了
que.push(nodeSocket(t.val / + (t.val & ), t.id, t.cnt + ));
} else if (it->val == t.val) {
ansSocker[t.id] = t.cnt;
ansComputer[it->id] = t.id;
ansc++;
ansu += t.cnt;
ss.erase(it);
}
}
printf("%d %d\n", ansc, ansu);
for (int i = ; i <= m; ++i) {
printf("%d ", ansSocker[i]);
}
printf("\n");
for (int i = ; i <= n; ++i) {
printf("%d ", ansComputer[i]);
}
printf("\n");
} int main() {
#ifdef local
freopen("data.txt","r",stdin);
#endif
work();
return ;
}
然而因为没个插头都会判断是否要用,该是要插多少个adapters的,还是要插。用一个普通队列来维护,能达到一样的效果。
时间就降下来了
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = + ;
struct nodeComputer {
int val, id;
bool operator < (const struct nodeComputer &rhs) const {
if (val != rhs.val) return val < rhs.val;
else return id < rhs.id;
}
nodeComputer(int a, int b) : val(a), id(b) {}
};
struct nodeSocket {
int val, id, cnt;
bool operator < (const struct nodeSocket &rhs) const {
if (cnt != rhs.cnt) return cnt > rhs.cnt;
else if (val != rhs.val) return val > rhs.val;
else return id > rhs.id;
}
nodeSocket(int a, int b, int c) : val(a), id(b), cnt(c) {}
};
set<struct nodeComputer>ss;
queue<struct nodeSocket>que;
int ansSocker[maxn];
int ansComputer[maxn];
void work() {
int n, m;
scanf("%d%d", &n, &m);
for (int i = ; i <= n; ++i) {
int val;
scanf("%d", &val);
ss.insert(nodeComputer(val, i));
}
// for (set<struct nodeComputer> :: iterator it = ss.begin(); it != ss.end(); ++it) {
// printf("%d %d\n", it->val, it->id);
// }
// set<struct nodeComputer> :: iterator it = ss.lower_bound(nodeComputer(1, 3));
// printf("%d\n", it == ss.end());
for (int i = ; i <= m; ++i) {
int val;
scanf("%d", &val);
que.push(nodeSocket(val, i, ));
}
int ansc = , ansu = ;
while (!que.empty()) {
struct nodeSocket t = que.front();
que.pop();
set<struct nodeComputer> :: iterator it = ss.lower_bound(nodeComputer(t.val, ));
if (it == ss.end() || it->val != t.val) {
if (t.val == ) continue; //再分解就没意思了
que.push(nodeSocket(t.val / + (t.val & ), t.id, t.cnt + ));
} else if (it->val == t.val) {
ansSocker[t.id] = t.cnt;
ansComputer[it->id] = t.id;
ansc++;
ansu += t.cnt;
ss.erase(it);
}
}
printf("%d %d\n", ansc, ansu);
for (int i = ; i <= m; ++i) {
printf("%d ", ansSocker[i]);
}
printf("\n");
for (int i = ; i <= n; ++i) {
printf("%d ", ansComputer[i]);
}
printf("\n");
} int main() {
#ifdef local
freopen("data.txt","r",stdin);
#endif
work();
return ;
}
Codeforces Round #377 (Div. 2) E. Sockets的更多相关文章
- Codeforces Round #377 (Div. 2) D. Exams
Codeforces Round #377 (Div. 2) D. Exams 题意:给你n个考试科目编号1~n以及他们所需要的复习时间ai;(复习时间不一定要连续的,可以分开,只要复习够ai天 ...
- Codeforces Round #377 (Div. 2)
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; in ...
- Codeforces Round #377 (Div. 2)D(二分)
题目链接:http://codeforces.com/contest/732/problem/D 题意: 在m天中要考k个课程, 数组a中有m个元素,表示第a[i]表示第i天可以进行哪门考试,若a[i ...
- Codeforces Round #377 (Div. 2) D. Exams 贪心 + 简单模拟
http://codeforces.com/contest/732/problem/D 这题我发现很多人用二分答案,但是是不用的. 我们统计一个数值all表示要准备考试的所有日子和.+m(这些时间用来 ...
- Codeforces Round #377 (Div. 2) 被坑了
http://codeforces.com/contest/732/problem/B 题目要求任意两个连续的日子都要 >= k 那么如果a[1] + a[2] < k,就要把a[2]加上 ...
- Codeforces Round #377 (Div. 2)A,B,C,D【二分】
PS:这一场真的是上分场,只要手速快就行.然而在自己做的时候不用翻译软件,看题非常吃力非常慢,还有给队友讲D题如何判断的时候又犯了一个毛病,一定要心平气和,比赛也要保证,不要用翻译软件做题: Code ...
- Codeforces Round #377 (Div. 2) B. Cormen — The Best Friend Of a Man(贪心)
传送门 Description Recently a dog was bought for Polycarp. The dog's name is Cormen. Now Polycarp has ...
- Codeforces Round #377 (Div. 2) D. Exams(二分答案)
D. Exams Problem Description: Vasiliy has an exam period which will continue for n days. He has to p ...
- Codeforces Round #377 (Div. 2) C. Sanatorium 水题
C. Sanatorium time limit per test 1 second memory limit per test 256 megabytes input standard input ...
随机推荐
- SoundHound Inc. Programming Contest 2018
A - F Time Limit: 2 sec / Memory Limit: 1024 MB Score : 100100 points Problem Statement You are give ...
- 1080 Graduate Admission (30)(30 分)
It is said that in 2013, there were about 100 graduate schools ready to proceed over 40,000 applicat ...
- HDU4027(线段树单点更新区间)
Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65768/65768 K ...
- Scala学习——array与arraybuffer的区别(初)
1.由于Array是不可变的,所以不能直接地对其元素进行删除操作,只能通过重赋值或过滤生成新的Array的方式来删除不要的元素. 而ArrayBuffer是可变的,本身提供了很多元素的操作,当然包括删 ...
- centos7 install python3
1. 过程 # 1. root权限, 安装依赖 yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-dev ...
- SQL 调用 webservice
webservice 需要配置为get 方式 sp_configure 'show advanced options', 1; GO RECONFIGURE; GO sp_configure 'Ole ...
- <c和指针>学习笔记3之函数和数组
1 函数声明 (1)原型 告诉编译器函数的参数数量和每个参数的类型以及返回值的类型.编译器通过检查原型之后,就可以检查这个函数得调用,从而来确保参数正确,返回值无误. 通用技巧,将原型写在一个头文件当 ...
- QDUOJ ycb的ACM进阶之路 二进制多重背包
ycb的ACM进阶之路 发布时间: 2017年5月22日 14:30 最后更新: 2017年5月22日 14:31 时间限制: 1000ms 内存限制: 128M 描述 ycb是个天资聪颖 ...
- JS Guid生成
function numToGuid(uid) { var str = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"; var l = uid.to ...
- 一文带你认识Java8中接口的默认方法
Java8是Oracle于2014年3月发布的一个重要版本,其API在现存的接口上引入了非常多的新方法. 例如,Java8的List接口新增了sort方法.在Java8之前,则每个实现了List接口的 ...