BZOJ 3330 分数

图都画给你了。。。三分妥妥的。

要注意细节,比如/0这种。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 25
#define eps 1e-7
using namespace std;
int n,bit;
long double st[maxn],sc[maxn],po[maxn],ans;
long double calc2(long double x,long double y)
{
    long double ret=0;
    for (int i=1;i<=n;i++)
    {
        sc[i]=(long double)100/((long double)1+exp(x-y*st[i]));
        if (sc[i]<=eps || sc[i]>=100) return 1e200;
        ret+=po[i]*log((long double)100/sc[i])+(100-po[i])*log((long double)100/((long double)100-sc[i]));
    }
    return ret;
}
long double calc1(long double x)
{
    long double l=0,r=1,l1,l2;
    while (r-l>eps)
    {
        l1=(l+r)/2;l2=(l1+r)/2;
        if (calc2(x,l1)<=calc2(x,l2)) r=l2;else l=l1;
    }
    return calc2(x,l);
}
void print()  
{  
    long long a=ans;  
    int digit=0;  
    for(int tmp=a;tmp;tmp/=10) digit++;  
    if(bit<=digit)  
    {  
        int bits[100];  
        for(*bits=0;a;a/=10) bits[++*bits]=a%10;  
        for(int i=*bits;i>=1 && bit;i--,digit--,bit--)  
        {  
            putchar(bits[i]+'0');  
        }  
        while(digit--) putchar('0');  
    }  
    else  
    {  
        cout<<a<<'.';  
        bit-=digit;  
        while(bit--) ans-=(int)ans,ans*=10,printf("%d",(int)ans);  
    }  
}
int main()
{
    scanf("%d%d",&n,&bit);
    for (int i=1;i<=n;i++) scanf("%Lf",&st[i]);
    sort(st+1,st+n+1);
    po[1]=0;po[n]=100;for (int i=2;i<=n-1;i++) po[i]=(long double)(i-1)*100/(n-1);
    long double l=0,r=10,l1,l2;
    while (r-l>eps)
    {
        l1=(l+r)/2;l2=(l1+r)/2;
        if (calc1(l1)<=calc1(l2)) r=l2;else l=l1;
    }
    ans=calc1(l);
    print();
    return 0;    
}
原文地址:https://www.cnblogs.com/ziliuziliu/p/6411528.html