【2016-CCPC-C】二分,动脑筋(Car,hdu 5935)

比赛时看时间和路程都是整数,因此觉得速度也会是整数,因此走上了求因数的不归路。

后来才知道速度也可以是小数的。之所以会这样,只能说自己太浮躁吧。就像在用蛮力。其实自己做事可以细致一点,四两拨千斤。


后来看了别人说可以取小数,就用二分来求,然后超时。后来优化了下二分范围,然后就过了。936ms/1000ms。说明很多时候,像这种解法多样的题目,你可能会因为解法不够优秀而徘徊在超时的边缘,所以能优化下尽量优化下吧。优化了下输入输出811ms。


其实可以递推出答案的,用这一段的路程除以上一段的速度,就可以得到以上一段的速度通过这一段路程所需要的时间,时间可能是小数。因为时间必须是整数,而且速度只能增不能减,因此时间要向上取整。因为会有精度问题,所以可以用eps=1e-8处理或者用分数来表示。514ms。


二分代码

#include<bits/stdc++.h>
#define maxn 100010
using namespace std;

int N;
int a[maxn];

inline int readint()
{
    char c=getchar();
    while(!isdigit(c)) c=getchar();
    int x=0;
    while(isdigit(c))
    {
        x=x*10+c-'0';
        c=getchar();
    }
    return x;
}

inline void gt(int& x)
{
    char ch;
    bool fu;
    x=0;
    while(ch=getchar(),!(isdigit(ch)||ch=='-'));
    if(ch=='-')
    {
        fu=true;
        ch=getchar();
    }
    else fu=false;
    while(x*=10,x+=ch-'0',ch=getchar(),isdigit(ch));
    if(fu) x=-x;
}

inline gcd(int a,int b)
{
    if(a<b) swap(a,b);
    return a%b==0?b:gcd(b,a%b);
}

int main()
{
    int T;
    T=readint();
    for(int t=1;t<=T;t++)
    {
        N=readint();
        for(int i=1;i<=N;i++)
            a[i]=readint();
        int ans=1;
        int fz=a[N]-a[N-1];
        int fm=1;
        for(int i=N-1;i>=1;i--)
        {
            int d=a[i]-a[i-1];
            int FZ=d*fm;
            int FM=fz;
            int shijian;
            if(FZ%FM==0) shijian=FZ/FM;
            else shijian=FZ/FM+1;
            ans+=shijian;
            fz=a[i]-a[i-1];
            fm=shijian;
            int GCD=gcd(fz,fm);
            fz/=GCD;
            fm/=GCD;
        }
        printf("Case #%d: %d\n",t,ans);
    }
    return 0;
}
递推代码

#include<bits/stdc++.h>
#define maxn 100010
using namespace std;

int N;
int a[maxn];

int gcd(int a,int b)
{
    if(a<b) swap(a,b);
    return a%b==0?b:gcd(b,a%b);
}

int main()
{
    int T;
    scanf("%d",&T);
    for(int t=1;t<=T;t++)
    {
        scanf("%d",&N);
        for(int i=1;i<=N;i++)
            scanf("%d",&a[i]);
        int ans=1;
        int fz=a[N]-a[N-1];
        int fm=1;
        for(int i=N-1;i>=1;i--)
        {
            int d=a[i]-a[i-1];
            int FZ=d*fm;
            int FM=fz;
            int shijian;
            if(FZ%FM==0) shijian=FZ/FM;
            else shijian=FZ/FM+1;
            ans+=shijian;
            fz=a[i]-a[i-1];
            fm=shijian;
            int GCD=gcd(fz,fm);
            fz/=GCD;
            fm/=GCD;
        }
        printf("Case #%d: %d\n",t,ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值