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. JavaMail API的应用

    JavaMail API 是一个用于阅读.编写和发送电子消息的可选包(标准扩展),用来创建邮件用户代理(Mail User Agent,MUA)类型程序. JavaMail API 需要 JavaBe ...

  2. [acm]HDOJ 1200 To and Fro

    题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=1200 简单字符串处理,找规律 /* 11509672 2014-08-21 11:32:55 Acc ...

  3. Qt属性系统(Qt Property System)

    Qt提供了巧妙的属性系统,它与某些编译器支持的属性系统相似.然而,作为平台和编译器无关的库,Qt不能够依赖于那些非标准的编译器特性,比如__property 或者 [property].Qt的解决方案 ...

  4. 【Python】python2.7 安装配置OpenCV2

    环境:Ubuntu16.04 anaconda Python2.7 opencv2.4.13 安装opencv后 import cv2 遇到错误信息: No module named cv2 安装op ...

  5. Vue项目屏幕自适应方案

    安装lib-flexible cnpm i lib-flexible -D Vue项目引入 lib-flexible. main.js: import 'lib-flexible/flexible' ...

  6. 洛谷P1220关路灯——区间DP

    题目:https://www.luogu.org/problemnew/show/P1220 区间DP. 代码如下: #include<iostream> #include<cstd ...

  7. 把myeclipse中的web项目导入eclipse中不能编程web项目的解决办法

    title: 把myeclipse中的web项目导入eclipse中不能编程web项目的解决办法 tags: grammar_cjkRuby: true --- 右键单击项目,properties-- ...

  8. DS:目录

    ylbtech-DS:目录 1.返回顶部   2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部     6.返回顶部   作者:ylbtech出处:http://ylbtech.cn ...

  9. Jenkins Email Extension Plugin 邮件插件

    1:系统管理-管理插件-可选插件  搜索Email 可列出Email Extension Plugin插件 2:选择相应的插件点  下载并安装之后重启,等待 3:安装完后,自己去重启tomcat,先s ...

  10. HDU-5974

    A Simple Math Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Ot ...