比赛时看时间和路程都是整数,因此觉得速度也会是整数,因此走上了求因数的不归路。
后来才知道速度也可以是小数的。之所以会这样,只能说自己太浮躁吧。就像在用蛮力。其实自己做事可以细致一点,四两拨千斤。
后来看了别人说可以取小数,就用二分来求,然后超时。后来优化了下二分范围,然后就过了。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;
}