codeforces 732E(贪心)

题目链接:http://codeforces.com/contest/732/problem/E

题意:有n台计算机,m个插座,每台计算机有一个值a[i],每个插座有一个值b[i],每个插座最多只能对应一台计算机,且只有a[i] == b[j]时才能配对。现有无限台适配器,适配器能使b[i]减半,求最多能使多少计算机与插座配对(c),以及对应的最小的适配器个数(u)(即先考虑c最大,再使u最小)。

思路:先对计算机和插座按值排序,不断减半,发现能配对就配对。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N = 2e5 + 5;
 4 int a[N],b[N],c,u;
 5 struct node
 6 {
 7     int val,id;
 8     node(){}
 9     node(int v,int i) : val(v),id(i) {}
10     bool operator < (const node &t)
11     {
12         if(val != t.val)
13             return val < t.val;
14         return id < t.id;
15     }
16 }p[N],s[N];
17 map <int,int> mp;//计算机值出现的次数
18 int main()
19 {
20     int n,m;
21     scanf("%d %d",&n,&m);
22     for(int i = 1; i <= n; i++)
23     {
24         scanf("%d",&p[i].val);
25         p[i].id = i;
26         mp[p[i].val]++;
27     }
28     sort(p + 1, p + n + 1);
29     for(int i = 1; i <= m; i++)
30     {
31         scanf("%d",&s[i].val);
32         s[i].id = i;
33     }
34     sort(s + 1, s + m + 1);
35     for(int i = 1; i <= m; i++)
36     {
37         for(int j = 0; j < 31; j++)
38         {
39             if(mp.count(s[i].val))//发现可能匹配
40             {
41                 int t = lower_bound(p + 1, p + n + 1, node(s[i].val,0)) - p + mp[s[i].val] - 1;//找到位置(由于有可能有多个相同的值,这里先从最后一个开始往前推)
42                 if(p[t].val == s[i].val && !b[p[t].id])//值相等 && 该计算机还未匹配
43                 {
44                     b[p[t].id] = s[i].id;
45                     mp[s[i].val]--;//数量-1
46                     a[s[i].id] = j;
47                     c++;
48                     u += j;
49                     break;
50                 }
51             }
52             s[i].val = (s[i].val + 1) >> 1;
53         }
54     }
55     printf("%d %d\n",c,u);
56     for(int i = 1; i <= m; i++)
57         printf("%d ",a[i]);
58     printf("\n");
59     for(int i = 1; i <= n; i++)
60         printf("%d ",b[i]);
61     return 0;
62 }

 

posted on 2016-10-20 01:19  polarday  阅读(601)  评论(0编辑  收藏  举报

导航