题意:
给出一些给定功率的电脑和插座,只有功率匹配才能连接,另外有一些适配器,连在插座上可以把插座功率降为1/2,求最多匹配电脑数和需要的适配器数以及具体映射。
要点:
这题就是贪心+STL的应用,主要是贪心的证明,具体证明看下面这个博客:
参考博客:点击打开链接
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 300000;
map<int, int> pre;
vector<int> s[maxn];
int n, m, cnt;
int ans1[maxn], ans2[maxn];
struct node
{int x, pos;
}a[maxn];bool cmp(node a, node b)
{return a.x < b.x;
}int main()
{int i, x;scanf("%d%d", &n, &m);for (i = 1; i <= n; i++){scanf("%d", &x);int temp = pre[x];//pre数组把相同功率不同下标的电脑指向同一个位置if (temp == 0){pre[x] = ++cnt;s[cnt].push_back(i);//s提供相同功率的所有下标的电脑}elses[temp].push_back(i);}for (i = 1; i <= m; i++){scanf("%d", &a[i].x);a[i].pos = i;}sort(a + 1, a + 1 + m, cmp);int total = 0,num=0;for (i = 1; i <= m; i++){int sub = 0;x = a[i].x;while (x){int xx = pre[x];if (xx){int len = s[xx].size();if (len){int it = s[xx][len - 1];ans2[it] = a[i].pos;ans1[a[i].pos] = sub;s[xx].pop_back();total += sub;num++;break;}elsepre.erase(x);}if (x == 1)break;x = (x + 1) >> 1;sub++;}}printf("%d %d\n", num, total);for (i = 1; i <= m; i++)printf("%d%c", ans1[i], i == m ? '\n' : ' ');for (i = 1; i <= n; i++)printf("%d%c", ans2[i], i == n ? '\n' : ' ');return 0;
}