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 ...
随机推荐
- java中相对路径加载xml
一.xml文件一般的存放位置有三个: 1.放在WEB-INF下: 2.xml文件放在/WEB-INF/classes目录下或classpath的jar包中: 3.放在与解析它的java类同一个包中,不 ...
- storm相关技术
There are two kinds of nodes on a Storm cluster: the master node and the worker nodes. 有两种节点,主节点和wor ...
- HDU5875Function(单调队列)
The shorter, the simpler. With this problem, you should be convinced of this truth. You are giv ...
- 「LuoguP1144」 最短路计数(dijkstra
题目描述 给出一个NN个顶点MM条边的无向无权图,顶点编号为1-N1−N.问从顶点11开始,到其他每个点的最短路有几条. 输入输出格式 输入格式: 第一行包含22个正整数N,MN,M,为图的顶点数与边 ...
- 解析Monte-Carlo算法(基本原理,理论基础,应用实践)
引言 最近在和同学讨论研究Six Sigma(六西格玛)软件开发方法及CMMI相关问题时,遇到了需要使用Monte-Carlo算法模拟分布未知的多元一次概率密度分布问题.于是花了几天时间,通过查询相关 ...
- 微信小程序 加载 HTML 标签
肯定有小伙伴遇到过这个问题:加载的数据是一堆HTML 标签这就尴尬了,因为小程序没有提供 webview 来加载这些 HTML.但是不用慌,小程序不提供我们可以自己造个新轮子,自己造不出新轮子咱们找到 ...
- 用WINHEX合并两个或多个BIN文件
以前,我给W25Q16下载内容的时候,每次都要分别传输GBK字符.英文字符和图片BIN文件,每次都要传输好几次. 后来,我发现,用WINHEX软件可以把这些BIN文件都合并到一个文件,只需要传输一次就 ...
- GET请求中的乱码原理解析和解决方案
2. 乱码问题解决 基础知识 1)浏览器会在中文的UTF-8后加上上%得到URL编码 例如: %e8%b4%b9%e7%94%a8%e6%8a%a5%e9%94%80 2)以get的请求发送到to ...
- pkg_resources----Entry Points为程序提供扩展点
官方文档对Entry Points的介绍 Entry Points Entry points are a simple way for distributions to "advertise ...
- 2014 ACM广东省赛总结
2014年广东省赛在化工大学城开,5月10日开幕式&热身赛,5月11日正式赛. 热身赛的时候,开幕式说有两小时,于是我们愉快的切题了,像平常组队赛那样很快出了两题,但卡在后面两题切不动了.这时 ...