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的更多相关文章

  1. Codeforces Round #377 (Div. 2) D. Exams

    Codeforces Round #377 (Div. 2) D. Exams    题意:给你n个考试科目编号1~n以及他们所需要的复习时间ai;(复习时间不一定要连续的,可以分开,只要复习够ai天 ...

  2. Codeforces Round #377 (Div. 2)

    #include <iostream> #include <stdio.h> #include <string.h> using namespace std; in ...

  3. Codeforces Round #377 (Div. 2)D(二分)

    题目链接:http://codeforces.com/contest/732/problem/D 题意: 在m天中要考k个课程, 数组a中有m个元素,表示第a[i]表示第i天可以进行哪门考试,若a[i ...

  4. Codeforces Round #377 (Div. 2) D. Exams 贪心 + 简单模拟

    http://codeforces.com/contest/732/problem/D 这题我发现很多人用二分答案,但是是不用的. 我们统计一个数值all表示要准备考试的所有日子和.+m(这些时间用来 ...

  5. Codeforces Round #377 (Div. 2) 被坑了

    http://codeforces.com/contest/732/problem/B 题目要求任意两个连续的日子都要 >= k 那么如果a[1] + a[2] < k,就要把a[2]加上 ...

  6. Codeforces Round #377 (Div. 2)A,B,C,D【二分】

    PS:这一场真的是上分场,只要手速快就行.然而在自己做的时候不用翻译软件,看题非常吃力非常慢,还有给队友讲D题如何判断的时候又犯了一个毛病,一定要心平气和,比赛也要保证,不要用翻译软件做题: Code ...

  7. 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 ...

  8. 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 ...

  9. Codeforces Round #377 (Div. 2) C. Sanatorium 水题

    C. Sanatorium time limit per test 1 second memory limit per test 256 megabytes input standard input ...

随机推荐

  1. java中相对路径加载xml

    一.xml文件一般的存放位置有三个: 1.放在WEB-INF下: 2.xml文件放在/WEB-INF/classes目录下或classpath的jar包中: 3.放在与解析它的java类同一个包中,不 ...

  2. storm相关技术

    There are two kinds of nodes on a Storm cluster: the master node and the worker nodes. 有两种节点,主节点和wor ...

  3. HDU5875Function(单调队列)

    The shorter, the simpler. With this problem, you should be convinced of this truth.      You are giv ...

  4. 「LuoguP1144」 最短路计数(dijkstra

    题目描述 给出一个NN个顶点MM条边的无向无权图,顶点编号为1-N1−N.问从顶点11开始,到其他每个点的最短路有几条. 输入输出格式 输入格式: 第一行包含22个正整数N,MN,M,为图的顶点数与边 ...

  5. 解析Monte-Carlo算法(基本原理,理论基础,应用实践)

    引言 最近在和同学讨论研究Six Sigma(六西格玛)软件开发方法及CMMI相关问题时,遇到了需要使用Monte-Carlo算法模拟分布未知的多元一次概率密度分布问题.于是花了几天时间,通过查询相关 ...

  6. 微信小程序 加载 HTML 标签

    肯定有小伙伴遇到过这个问题:加载的数据是一堆HTML 标签这就尴尬了,因为小程序没有提供 webview 来加载这些 HTML.但是不用慌,小程序不提供我们可以自己造个新轮子,自己造不出新轮子咱们找到 ...

  7. 用WINHEX合并两个或多个BIN文件

    以前,我给W25Q16下载内容的时候,每次都要分别传输GBK字符.英文字符和图片BIN文件,每次都要传输好几次. 后来,我发现,用WINHEX软件可以把这些BIN文件都合并到一个文件,只需要传输一次就 ...

  8. GET请求中的乱码原理解析和解决方案

    2. 乱码问题解决 基础知识 1)浏览器会在中文的UTF-8后加上上%得到URL编码   例如: %e8%b4%b9%e7%94%a8%e6%8a%a5%e9%94%80 2)以get的请求发送到to ...

  9. pkg_resources----Entry Points为程序提供扩展点

    官方文档对Entry Points的介绍 Entry Points Entry points are a simple way for distributions to "advertise ...

  10. 2014 ACM广东省赛总结

    2014年广东省赛在化工大学城开,5月10日开幕式&热身赛,5月11日正式赛. 热身赛的时候,开幕式说有两小时,于是我们愉快的切题了,像平常组队赛那样很快出了两题,但卡在后面两题切不动了.这时 ...