ACM/ICPC 2018亚洲区预选赛北京赛站网络赛 K-Dimensional Foil II(二分瞎搞)

 

传送门

这题其实没有题面看起来复杂,实际上我们贪心的去想:对于下式

                                                                          S=\sum\limits_{i=1}^Na_i^2

如果我们有这么一种操作可以把某个a_i减一,现在问一次操作后S的最小值,

那么很容易便可以知道我们肯定是去找最大的那个去减一,最后的结果才会最小.

对于这道题其实也一样,我们肯定也是选相对于圆心数值的差(加绝对值)大的维度优先去减小,这样一直贪心下去,

最后落到上面的点肯定就是我们要求的点。

对于这样一种操作,我们可以发现,在经过若干次操作后,这k个维度的向量的长度的最大的那几个肯定数值是相等的,

这是由于我们贪心的选取最大的去减所导致的,由于我们每次减的数值很小,误差小于题目中给的1e-4,那么对于结果来说数值就是无误的.

这样一来,对于这么些操作我们便可以用二分去替代,二分我们最后划定的那个最大值的数值便可以解决此问题。

 

#include<bits/stdc++.h>
using namespace std;
double eps=1e-6;
double c[105],s[105];
double conv[105];
double ans[105];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,k,r;
        scanf("%d%d",&n,&k);
        scanf("%d",&r);
        for(int i=1;i<=k;i++) scanf("%lf",&c[i]);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=k;j++) scanf("%lf",&s[j]),conv[j]=abs(s[j]-c[j]);
            double L=0,R=1e8;
            while(L<R-eps)
            {
                double mid=(L+R)/2.0;
                double sum=0;
                for(int j=1;j<=k;j++) sum+=max(0.0,conv[j]-mid);
                if(sum<=r) R=mid;
                else L=mid;
            }
            for(int j=1;j<=k;j++)
            {
                if(conv[j]>=R) conv[j]=R;
                if(s[j]>c[j]) ans[j]=-conv[j]+s[j];
                else ans[j]=conv[j]+s[j];
                printf("%.5f ",ans[j]);
            }
            printf("\n");
        }
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值