2021.1.28 个人rating赛补题报告

B. Knights of a Polygonal Table

1.题意

  给定n个骑士,每人都有自己的武力值和若干金币,如果第一个骑士的武力值大于第二个骑士,那么第一个骑士就能获取第二个骑士的所有金币,每个骑士最多只能击败k个骑士。对于每个骑士,求出

决斗后他的金币的最大值。

2.题解

  结构体存骑士的信息,显然k最小,就以武力值排序,找到比他武力值小的所有骑士,然后用优先队列动态维护这些骑士金钱前k大的即可。

3.代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e5 + 5;
int n, m, a[maxn];
ll ans[maxn];
struct knight {
    int pow, coin, index;
    knight() {
        index = pow = coin = 0;
    }
}k[maxn];
struct node {
    priority_queue<int>q;
    ll sum;
}ss;
bool cmp(knight a, knight b) {
	return a.pow < b.pow; 
}
int main() {
	scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) {
    	scanf("%d", &k[i].pow);
		a[i] = k[i].pow;
	}
    for(int i = 1; i <= n; i++) {
    	scanf("%d", &k[i].coin);
    	k[i].index = i;	
	}
	
    if(m == 0) {
        for(int i = 1; i <= n; i++) {
        	printf("%d ", k[i].coin);
		}
        return 0;
    }
    if(n == 1) {
        printf("%d ", k[1].coin);
        return 0;
    }
    
    sort(k + 1, k + n + 1, cmp);
    for(int i = 1; i <= m + 1; i++) {
        for(int j = 1; j <= i; j++) {
            ans[k[i].index] += (ll)k[j].coin;
        }
    }
    for(int i = 1; i <= m; i++) {
    	ss.q.push(-k[i].coin);
		ss.sum += k[i].coin;
	}
    if(k[m + 1].coin > -ss.q.top()) {
        ss.sum -= -ss.q.top();
        ss.q.pop();
        ss.q.push(-k[m + 1].coin);
        ss.sum += k[m + 1].coin;
    }
    for(int i = m + 2; i <= n; i++) {
        ans[k[i].index] += k[i].coin;
        ans[k[i].index] += ss.sum;
        if(k[i].coin > -ss.q.top()) {
            ss.sum -= -ss.q.top();
            ss.q.pop();
            ss.q.push(-k[i].coin);
            ss.sum += k[i].coin;
        }	
    }
    for(int i = 1; i <= n ; i++) {
    	printf("%lld ", ans[i]);
	}
    
    return 0;
} 

  

原文地址:https://www.cnblogs.com/lvguapi/p/14364369.html