题意: 给定
n
个插座,每个插座的电压是
思路:比较显然的是能匹配的尽量匹配,不能匹配时,尽量使用插减压器少的。用一个 pair⟨int,int⟩ 来维护某个插座的当前电压和当前的减压器个数。然后从大到小遍历插头,将过大的插座的 (⌈first⌉,second+1) 后返回队列.直到找到第一个合适的或不合适的。直到遍历完所有的插头。
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <queue>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int MAXN = 200000 + 10;
int cot[MAXN];
int net[MAXN];
struct node
{
int val, num;
int pos;
node(int _val=0, int _num=0,int _pos=0) :val(_val), num(_num),pos(_pos){}
};
struct cmp
{
bool operator()(const node &x, const node &y)
{
if (x.val != y.val)return x.val<y.val;
return x.num > y.num;
}
};
int main()
{
priority_queue<node, vector<node>, cmp>pq;
memset(cot, 0, sizeof cot);
memset(net, 0, sizeof net);
int n,m;
scanf("%d%d", &n, &m);
vector<pii>v;
for (int i = 0; i < n; i++)
{
int pow;
scanf("%d", &pow);
v.push_back(pii(pow, i));;
}
sort(v.begin(), v.end(), [](const pii& x, const pii&y){return x.first < y.first; });
for (int i = 0; i < m; i++)
{
int pow;
scanf("%d", &pow);
pq.push(node(pow, 0,i));
}
int maxx = 0; int minn = 0;
for (int i = v.size() - 1; i >= 0; i--)
{
while (pq.size()&&pq.top().val>v[i].first)
{
node tmp = pq.top();
pq.pop();
tmp.val = ceil(tmp.val*1.0 / 2.0), tmp.num++;
if (tmp.val == 0)continue;
pq.push(tmp);
}
if (pq.size() == 0)break;
if (pq.top().val == v[i].first)
{
maxx++;
minn += pq.top().num;
cot[pq.top().pos] = pq.top().num;
net[v[i].second] = pq.top().pos+1;
pq.pop();
}
else if (pq.top().val < v[i].first)continue;
}
printf("%d %d\n", maxx, minn);
for (int i = 0; i < m; i++)
{
if (i)printf(" ");
printf("%d", cot[i]);
}
printf("\n");
for (int i = 0; i < n; i++)
{
if (i)printf(" ");
printf("%d", net[i]);
}
printf("\n");
//system("pause");
}