B5090 组题 二分答案

bzoj有毒,看不了自己哪错了。。。根本没法debug、

我到现在还是不知道自己代码为什么会T,二分次数也加限制了,但是还是T。。。救命啊!!!

题干:

Description
著名出题人小Q的备忘录上共有n道可以出的题目,按照顺序依次编号为1到n,其中第i道题目的难度系数被小Q估计
为a_i,难度系数越高,题目越难,负数表示这道题目非常简单。小Q现在要出一套难题,他决定从备忘录中选取编
号连续的若干道题目,使得平均难度系数最高。当然,小Q不能做得太过分,一套题目必须至少包含k道题目,因此
他不能通过直接选取难度系数最高的那道题目来组成一套题。请写一个程序,帮助小Q挑选平均难度系数最高的题
目。
Input
第一行包含两个整数n,k(1<=n<=100000,1<=k<=n),分别表示题目的总量和题数的下界。
第二行包含n个整数a_1,a_2,...,a_n(|a_i|<=10^8),分别表示每道题目的难度系数。
Output

 输出一个既约分数p/q或-p/q,即平均难度系数的最大值。
Sample Input
5 3

1 4 -2 -3 6
Sample Output
5/4
HINT

Source

claris原创,本oj版权所有,翻版必究

我的代码:(蜜汁TLE)

#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(int i = a;i <= n;i++)
#define lv(i,a,n) for(int i = a;i >= n;i--)
#define clean(a) memset(a,0,sizeof(a))
const int INF = 1 << 30;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
        if(c == '-') op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
        x = x * 10 + c - '0';
    if(op) x = -x;
}
template <class T>
void write(T x)
{
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) write(x / 10);
    putchar('0' + x % 10);
}
db a[100010];
db s[100010];
db g[100010];
int mn[100010];
db eps = 1e-7;
int n,k,ok = 0;;ll y,x;
db l,r;
ll gcd(ll a,ll b)
{
    if(!b)
        return a;
    else
        return gcd(b,a % b);
}
int main()
{
    read(n);read(k);
    l=-100000000,r=100000000;
    duke(i,1,n)
    {
        scanf("%lf",&a[i]);
        s[i] = s[i - 1] + a[i];
    }
    duke(p,1,50)
    {
        ok = 0;
        db mid = (l + r) / 2;
        duke(i,1,n)
        {
            g[i] = s[i] - (db)i * mid;
        }
        /*duke(i,1,n)
        cout<<g[i]<<" ";
        cout<<endl;*/
        duke(i,1,n)
        {
            if(g[i] < g[mn[i - 1]])
                mn[i] = i;
            else
                mn[i] = mn[i - 1];
        }
        duke(i,k,n)
        {
            if(g[i] > g[mn[i - k]])
            {
                x = s[i] - s[mn[i - k]];
                y = i - mn[i - k];
                ok = 1;
                break;
            }
        }
        if(ok == 1)
        {
            l = mid;
        }
        else
        {
            r = mid;
        }
    }
    ll g = gcd(x,y);
    if(g < 0)
    g = -g;
    if(g)
    x /= g,y /= g;
    printf("%lld/%lld\n",x,y);
    return 0;
}
/*
5 3
1 4 -2 -3 6
*/

网上的AC代码:

#include<cstdio>
#include<algorithm>
#include<cctype>
using namespace std;
typedef double db;
typedef long long ll;
const int N=1e5+10;

int n,k,a[N],mn[N];
ll s[N],A,B,T;
db b[N];

inline int rd()
{
    char ch=getchar();
    int x=0,f=1;
    while(!isdigit(ch))
    {
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        x=x*10+(ch^48);
        ch=getchar();
    }
    return x*f;
}

bool check(db mid)
{
    int i,j;
    b[1]=a[1]-mid;
    for(i=2; i<=n; ++i)
    {
        b[i]=b[i-1]+a[i]-mid;
        mn[i]= b[i] < b[mn[i-1]]? i:mn[i-1];
    }
    for(i = k; i<=n; ++i)
    {
        if(b[i]>b[mn[i-k]])
        {
            A = s[i] - s[mn[i-k]];
            B = i - mn[i-k];
            return true;
        }
    }
    return false;
}
inline ll gcd(ll x,ll y)
{
    return !y? x:gcd(y,x%y);
}

int main()
{
    int i,j;
    n=rd();
    k=rd();
    for(i=1; i<=n; ++i)
    {
        a[i]=rd();
        s[i]=s[i-1]+a[i];
    }
    db l=-1e8,r=1e8,mid;
    mn[1]=1;
    for(i=1; i<=50; ++i)
    {
        mid=(l+r)/2;
        if(check(mid)) l=mid;
        else r=mid;
    }
    T=gcd(A,B);
    if(T<0) T=-T;
    if(T) A/=T,B/=T;
    printf("%lld/%lld\n",A,B);
}

没有任何区别好不好!为什么TLE?

猜你喜欢

转载自www.cnblogs.com/DukeLv/p/9504064.html