P9948 [USACO20JAN] Race B 题解
Treap_Kongzs · · 题解
备赛USACO25JAN祭
P9948 [USACO20JAN] Race B 题解
题面分析
零帧起手从
-
加速
1\space m/s -
减速
1\space m/s -
维持原速
当冲过
解法分析
首先,为了使时间最小化,我们不会且不可以随意减速。
那只要还没到终点,我们就放肆加速,这样时间肯定是最小的。然而终点限速为
然而求完成这个距离的时间显然不好写程序,那我们倒过来,求运动多少秒会达到甚至超出这个距离呢?
因为是先加速后减速,所以一定存在一个最大速度
-
对于前面的
零帧起手从零加速阶段,我们直接用while循环累加算出距离。 -
后面的减速阶段是从
maxv 减速到X ,我们可以视作从X 到maxv 的加速过程,这样就可以和上面的加速过程放在一起处理。
当我们两个阶段的距离之和第一次大于等于题面的距离时,就说明我们找到了最小的
设两个变量
我们打一下样例的数据表验证一下:
k = 10 x = 1
updis downdis t
1 0 1
1 1 2
3 1 3
3 3 4
6 3 5
6 6 6
k = 10 x = 2
updis downdis t
1 0 1
3 0 2
3 2 3
6 2 4
6 5 5
k = 10 x = 3
updis downdis t
1 0 1
3 0 2
6 0 3
6 3 4
10 3 5
k = 10 x = 4
updis downdis t
1 0 1
3 0 2
6 0 3
10 0 4
k = 10 x = 5
updis downdis t
1 0 1
3 0 2
6 0 3
10 0 4
这个\t的支持太糟糕了
我们发现,其实这个题目包含三种情况:
表现在图像上是三段运动,即加速、以
表现在图象上是直接转折,两段运动。就是取得到
- 从头到尾
downdis 就没累加过,只加了updis 就退出了(如样例第4,5 组数据)。
在图象上就是一条直线往上冲,不转折向下了。
你想,如果还没加速到
如果正面讨论这三种情况,那该多么痛苦!我们的
算法分析
没有二分,没有数学,算不上贪心,我们就是小模拟。
题目有
所以复杂度为
总时间复杂度为
源码分享
#include<bits/stdc++.h>
using namespace std;
int solve(int dis,int maxv)
{
int ans=0;
int updis=0,downdis=0;
int v=0;
//cout<<"k = "<<dis<<"\tx = "<<maxv<<endl;
//cout<<"updis\tdowndis\tt\n";
while(1)
{
v++;
updis+=v;
ans++;
//cout<<updis<<'\t'<<downdis<<'\t'<<ans<<endl;
if(updis+downdis>=dis)return ans;//累加一个就退出
if(v>=maxv)
{
downdis+=v;
ans++;
//cout<<updis<<'\t'<<downdis<<'\t'<<ans<<endl;
if(updis+downdis>=dis)return ans;//累加两个才退出
}
}
}
int main()
{
int k=0,n=0;
cin>>k>>n;
for(int i=1;i<=n;i++)
{
int x=0;
cin>>x;
cout<<solve(k,x);
if(i<n)cout<<endl;
}
return 0;
}
参考链接
官方题解
感谢希沃白板满足了我画图软件的需求(