题解:2024牛客多校第三场 B

B Crash Test header

时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 1048576K,其他语言2097152K
64bit IO Format: %lld

题目描述

After five years, the most high-profile event in motor racing, Formula 1, returns to China. The Chinese Grand Prix was recently held at the Shanghai International Circuit. Formula 1 cars can reach speeds of up to 350 km/h. To ensure the safety of the drivers, the cars must pass rigorous crash tests.

We consider the following simplified version of a crash test. Initially, a car is positioned with its front facing a wall, at a distance of D D D meters from the wall. This crash test provides n n n types of boosters, where the i i i-th type of booster has a thrust performance of h i h_i hi , and there are ample quantities of each type of booster. Suppose the current distance between the car’s front and the wall is d d d, and we use a booster with a thrust performance of h h h. When d ≥ h d≥h dh, the car will move forward h h h meters and then stop. Otherwise, the car will move forward d d d meters, crash into the wall, and rebound h − d h-d hd meters, after which it stops, still facing the wall.

Now, you want to know, through any number of operations (including no operation), what the minimum distance between the car’s front and the wall can be?

时隔五年,赛车界最受瞩目的赛事一级方程式赛车重返中国。中国大奖赛最近在上海国际赛车场举行。一级方程式赛车的时速可达 350 公里。为了确保车手的安全,赛车必须通过严格的碰撞测试。

我们考虑以下简化版的碰撞测试。起初,汽车的前部朝向墙壁,与墙壁的距离为 D D D 米。该碰撞测试提供了 n n n 种助推器,其中第 i$ 种助推器的推力性能为 h i h_i hi,每种助推器的数量都很充足。假设当前车头与墙壁之间的距离为 d d d,我们使用的助推器的推力性能为 h h h。当 d ≥ h d≥h dh 时,汽车将向前行驶 h h h 米,然后停止。否则,汽车将向前行驶 d d d 米,撞到墙上,反弹 h − d h-d hd 米,然后停下来,仍然面向墙壁。

现在,你想知道,通过任意多次运算(包括不运算),汽车车头与墙壁之间的最小距离是多少?

输入描述:

The first line of input contains two positive integers n n n and D ( 1 ≤ n ≤ 100 , 1 ≤ D ≤ 1 0 18 ) D (1≤n≤100,1≤D≤10^{18} ) D(1n100,1D1018), denoting the number of boosters and the distance between the Formula 1 car and the wall, respectively.

The second line of inputcontains n positive integers h 1 , h 2 , … , h n ( 1 ≤ h i ≤ 1 0 18 ) h_1 ,h _2 ,\dots ,h_n(1≤h_i≤10^{18} ) h1,h2,,hn(1hi1018), denoting the thrust performance of each booster.

第一行输入包含两个正整数 n n n D ( 1 ≤ n ≤ 100 , 1 ≤ D ≤ 1 0 18 ) D (1≤n≤100,1≤D≤10^{18} ) D(1n100,1D1018),分别表示助推器的数量和一级方程式赛车与墙壁之间的距离。

第二行输入包含 n 个正整数 h 1 , h 2 , … , h n ( 1 ≤ h i ≤ 1 0 18 ) h_1 ,h _2 ,\dots ,h_n(1≤h_i≤10^{18} ) h1,h2,,hn(1hi1018) ,表示每个助推器的推力性能。

输出描述:

Output an integer in a line, denoting the minimum possible distance between the car’s front and the wall.

在一行中输出一个整数,表示车头与墙壁之间可能的最小距离。

示例1

输入
1 10
3
输出
1
说明

An optimal strategy is 10 → i = 1 7 → i = 1 4 → i = 1 1 10 \xrightarrow[]{i=1} 7 \xrightarrow[]{i=1} 4 \xrightarrow[]{i=1} 1 10i=1 7i=1 4i=1 1

最佳策略是 10 → i = 1 7 → i = 1 4 → i = 1 1 10 \xrightarrow[]{i=1} 7 \xrightarrow[]{i=1} 4 \xrightarrow[]{i=1} 1 10i=1 7i=1 4i=1 1

示例2

输入
2 10
3 4
输出
0
说明

An optimal strategy is 10 → i = 1 7 → i = 2 3 → i = 1 0 10 \xrightarrow[]{i=1} 7 \xrightarrow[]{i=2} 3 \xrightarrow[]{i=1} 0 10i=1 7i=2 3i=1 0

最佳策略是 10 → i = 1 7 → i = 2 3 → i = 1 0 10 \xrightarrow[]{i=1} 7 \xrightarrow[]{i=2} 3 \xrightarrow[]{i=1} 0 10i=1 7i=2 3i=1 0

示例3

输入
2 1
3 7
输出
0
说明

An optimal strategy is 2 → i = 2 6 → i = 1 3 → i = 1 0 2 \xrightarrow[]{i=2} 6 \xrightarrow[]{i=1} 3 \xrightarrow[]{i=1} 0 2i=2 6i=1 3i=1 0

最佳策略是 2 → i = 2 6 → i = 1 3 → i = 1 0 2 \xrightarrow[]{i=2} 6 \xrightarrow[]{i=1} 3 \xrightarrow[]{i=1} 0 2i=2 6i=1 3i=1 0

示例4

输入
10 4306315981482911
4306 3519 8148 2911 9970 7222 5462 1844 7072 1702
输出
0

示例5

输入
10 123456789987654321
10 10 10 10 10 10 10 10 10 10
输出
1

题解

by W.Sherlock.Henry
这题可以运用到数论中的裴蜀定理
不懂的可以看这里
简而言之,就是:

a的任意倍数与b的任意倍数的和 都是 a和b的最大公约数的倍数

可以很明显地看到,假设我们只选一种操作,那么每种操作得到的最靠近的墙边的距离是

std::min(D % hi , hi - D % hi);

结合全部来看
那么总的答案就应该是

std::min(D % h_gcd , h_gcd - D % h_gcd);

我的代码

#include <iostream>
#include <algorithm>
#define int long long

int n,d;
const int N = 1e7+10;
int a[N];

signed main() {
    std::cin >> n >> d;
    for(int i = 0 ; i < n ; i ++) {
         std::cin >> a[i];
    }

    int m = a[0];
    for(int i =- 0 ; i < n ; i ++) {
        m = std::__gcd(m,a[i]);
    }

    std::cout << std::min(d%m,m - d%m);
    return 0;
}

转载自博客https://www.cnblogs.com/jiejiejiang2004/p/18321067
博主已同意,我就是博主

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值