为什么我会在这么简单的题上挂分??!!

· · 题解

想跳了。

观察数据范围,我们发现 a 很大,但 b 很小,所以我们想到时间复杂度很有可能和 b 有关。思考一会不难发现,当 b 减到 1 时,a 必然为 b 的倍数,满足题目条件,所以答案至多是 b-1,那么 b 最后的取值最多就是从 12 \times b - 1 ,共 2 \times b - 1 种可能,于是我们就可以枚举 b 最后的取值。

我们确定了 b 的取值,接下来就要找对应的最佳的 a 的最后的取值,就是让我们找到离原来的 a 最近的是 b 的倍数的数。我们可以先求出最大的整数 k,使得 k \times b \le a,然后我们要求的数即为 k \times b(k+1) \times b 这两个数之一,谁和 a 相减的绝对值越小,a 最后的取值就是谁。注意到我们上面的 k 可能为 0,而题目要求要时刻保证 a \ge 1, b \ge 1,这种情况显然 a 最后的取值不可能是 k \times b,所以 a 的取值就只可能是 (k+1) \times b

作者考场上没考虑 k0 的情况,爽挂分,哈哈哈。

::::info[代码]

#include<bits/stdc++.h>
#define code using
#define by namespace
#define dong0717 std;
code by dong0717
#define int long long
const int N=1e6+5,Mod=998244353;
void solve(){
    int a,b;
    cin>>a>>b;
    int ans=1e9;
    for(int i=1;i<=b+b;i++){//枚举b最后的取值
        int k=a/i;
        int x;//计算a最后的取值,这里x是a到最后a的取值的操作次数
        if(k==0)//记得特判!!!
            x=abs((k+1)*i-a);
        else
            x=min(abs(k*i-a),abs((k+1)*i-a));
        ans=min(ans,abs(b-i)+x);
    }
    cout<<ans;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int t=1;
    while(t--)
        solve();
    return 0;
}

::::