您的位置:首页 > 其它

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

2016-10-29 23:27 369 查看
比赛时看时间和路程都是整数,因此觉得速度也会是整数,因此走上了求因数的不归路。

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

后来看了别人说可以取小数,就用二分来求,然后超时。后来优化了下二分范围,然后就过了。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
-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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: