A题(贪心)
由题意得,要让斜边长度之和最小,就要让每次打磨产生的贡献最大,共建可以理解为打磨前后的长度差,通过结构体排序这个长度差还有相应的直角边(结构体部分参考大佬的),由于w比较小,直接循环暴力,用优先队列进行维护,要注意可能存在w用不完的情况,所以需要将y小到不能打磨的情况单独计算并
#include <bits/stdc++.h>
using namespace std;
double m(double x,double y){
    return sqrt(x*x+y*y)-sqrt(x*x+(y-1)*(y-1));
}
struct vbr{
    double z,x,y;
    bool operator<(const vbr other) const{
        return z < other.z;
    }
};
int main(){
    int n,w;cin>>n>>w;
    double ans=0;
    priority_queue<vbr> p;
    for(int i=1;i<=n;i++){
        double x,y;
        cin>>x>>y;
        vbr M1={m(x,y),x,y};
        if(y<1){
            ans+=sqrt(x*x+y*y);
            continue;
        }
        p.push(M1);
    }
    while(w--&&!p.empty()){
        vbr M2=p.top();
        p.pop();
        if(M2.y<1){
            ans+=sqrt(M2.x*M2.x+M2.y*M2.y);
            w++;
            continue;
        }
        vbr M3={m(M2.x,M2.y-1),M2.x,M2.y-1};
        p.push(M3);
    }
    while(!p.empty()){
        vbr M=p.top();
        p.pop();
        ans+=sqrt(M.x*M.x+M.y*M.y);
    }
    cout<<fixed<<setprecision(6)<<ans;
}
进行出队