codeforces 732E. Sockets

来源:互联网 发布:插补算法分类 编辑:程序博客网 时间:2024/06/11 13:51

题目的题意就不多说了,这个题我做的时候想了很久。写完代码之后,提交也是一直WA17。一直在考虑是不是自己的想法有问题。后来看了别人的代码。发现其实,解决问题的思想是一样的。我的想法是枚举每个插座要接的转换器的数量,然后依次判断每个电脑是不是正好可以连接上。但是我是用二分来实现查找的(我是将插座安电量排序,然后根据电脑电量找插座),因为涉及到会有相同的电量的插座,查找的时候加了一些小技巧,让它每次找到的都是第一个没有被使用的插座。但是可能实现上有bug,一直在WA。看了别人的代码,感觉被教育了。他们使用的是multiset,我最开始也想用,但是由于不熟悉,再加上我刚开始想的是如果把插座的电量存到multiset的话,每次还要更新整个multiset,不是很麻烦吗?结果,其实,看完别人的代码后,才发现自己的思维有点狭隘,既然不能存插座的电量,那存一个不会变的电脑电量不就好了。不说了,根据别人的思想,贴上自己实现的代码。至于那个二分的方法,等我好好研究一下有结果了在发博客吧!

#include <cstdio>#include <cstring>#include <cmath>#include <set>#include <algorithm>using namespace std;const int MAX = 200010;int s[MAX], a[MAX], b[MAX], vis[MAX];struct Node{int x, v;bool operator < (const Node& args) const{return v < args.v;}//注:定义了<,==和>以及>=,<=就都确定了,STL的比较关系都是用<来确定的,所以必须通    过定义< --“严格弱小于”来确定比较关};multiset<Node> P;void init(){P.clear();memset(a, 0, sizeof(a));memset(b, 0, sizeof(b));memset(vis, 0, sizeof(vis));}int main(){int n, m;while (scanf("%d%d",&n, &m) != EOF){Node tmp;for (int i = 1; i<=n; i++){scanf("%d", &tmp.v);tmp.x = i;P.insert(tmp);}for (int i = 1; i<=m; i++){scanf("%d",&s[i]);}init();//for (int i = 1; i<=m; i++) printf("%d %d\n", s[i].x, s[i].v);int cnt = 0, u = 0, c = 0;while (cnt <= 31){multiset<Node>::iterator it;for (int i = 1; i<=m; i++) if (!vis[i]){tmp.x = 0;tmp.v = s[i];it = P.find(tmp);if (it != P.end()){b[it->x] = i;a[i] = cnt;c++;u += cnt;vis[i] = 1;P.erase(it);}}for (int i = 1; i<=m; i++) s[i] = (s[i]+1) / 2;cnt++;}printf("%d %d\n", c, u);printf("%d", a[1]);for (int i = 2; i<=m; i++) printf(" %d", a[i]); printf("\n");printf("%d", b[1]);for (int i = 2; i<=n; i++) printf(" %d", b[i]); printf("\n");}return 0;}


0 0
原创粉丝点击