2020 JAN BRONZE 3.Race

描述


  Bessie 正在参加一场 K(1≤K≤109)米的跑步比赛。她从 0 米每秒的速度开始比赛。在每一秒中,她可以选择将她的速度增加 1 米每秒,保持速度不变,或者将她的速度减少 1 米每秒。例如,在第一秒中,她可以将她的速度增加到 1 米每秒,跑 1 米,或者保持她的速度 0 米每秒不变,跑 0 米。Bessie 的速度不会降低到小于零。

  Bessie 始终朝着终点线的方向跑,她想要花费整数秒的时间完成比赛。此外,她不想在终点时跑得太快:在 Bessie 跑完 K 米的时刻,她希望她的速度不超过 X(1≤X≤105)米每秒。Bessie 想要对于 N(1≤N≤1000)个不同的 X 值知道她多快可以完成比赛。

测试点性质:
  • 测试点 2-4 满足 N=X=1。
  • 测试点 5-10 没有额外限制。

输入
输入的第一行包含两个整数 K 和 N。

以下 N 行每行包含一个整数 X。
输出
输出 N 行,每行包含一个整数,表示 Bessie 完成比赛时的速度小于或等于 X 的情况下跑完 K 米需要的最小时间。
样例输入
10 5
1
2
3
4
5
样例输出
6
5
5
4
4
提示
当 X=1 时,一种最优方案为:
将速度增加到 1 米/秒,跑 1 米
将速度增加到 2 米/秒,跑 2 米,总计跑 3 米
将速度保持在 2 米/秒,总计跑 5 米
将速度保持在 2 米/秒,总计跑 7 米
将速度保持在 2 米/秒,总计跑 9 米
将速度降低到 1 米/秒,总计跑 10 米

当 X=3 时,一种最优方案为:
将速度增加到 1 米/秒,跑 1 米
将速度增加到 2 米/秒,总计跑 3 米
将速度增加到 3 米/秒,总计跑 6 米
将速度保持在 3 米/秒,总计跑 9 米
将速度保持在 3 米/秒,总计跑 12 米

注意当 X=3 时,以下方案是不合法的:
将速度增加到 1 米/秒,跑 1 米
将速度增加到 2 米/秒,总计跑 3 米
将速度增加到 3 米/秒,总计跑 6 米
将速度增加到 4 米/秒,总计跑 10 米

这是因为在 Bessie 跑完 10 米的时刻,她的速度是 4 米/秒。


分析

先让Bessie加速到最高速度m再减速到x(如果最高速度未达到x,那就是一直加速到最高速度),假设此时的走过的路程为s。

在保持匀速的情况下,如果k-s<最高速度m,那么就让k-s那个速度的时候跑多一秒,此时就是最短时间了。

如果k-s>=最高速度m,那相当于用最高速度m再跑(k-s)/m向下取整秒,再用速度(k-s)%m跑一秒。


代码
#include <cstdio>
#include <iostream>
using namespace std;
int j,k,n,len,ans;
bool check(long long x)
{
	long long a=(1+x)*x/2;
	long long b;
	if (x<j) b=0;
	else b=(j+x-1)*(x-j)/2;
	len=a+b;
	if (a+b<=k) return true;
	else return false; 
}
long long find_time()
{
	int l=1,r=1000000;
	while (l<=r)
	{
		int mid=(l+r)/2;
		if (check(mid))
		{
			ans=mid;
			l=mid+1;
		}else r=mid-1;
	}
	bool x=check(ans);
	long long t=ans;
	if (ans>=j) t+=ans-j;
	long long last=k-len;
	if (last!=0)
	{
		t+=last/ans;
		if (last%ans!=0) t++;
	 } 
	return t;
}
int main()
{
	scanf("%d%d",&k,&n);
	for (int i=1;i<=n;i++)
	  {
	  	  scanf("%d",&j);
	  	  long long t=find_time();
	  	  cout<<t<<endl;
	  }
	return 0;  
}

给个赞和关注吧

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值