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 }