如何使此代码更短以更快地完成

How to make this code shorter to do faster

本文关键字:何使此 代码      更新时间:2023-10-16

我是新的 c++ 学习者。我登录了Codeforce网站,这是11A问题:如果 ai - 1

给你一个序列 b0, b1, ..., bn - 1 和一个正整数 d。在每次移动中,您可以选择给定序列中的一个元素并向其添加 d。使给定序列增加所需的最少移动次数是多少?

输入输入的第一行包含两个整数 n 和 d(2 ≤ n ≤ 2000,1 ≤ d ≤ 106)。第二行包含空格分隔的序列 b0, b1, ..., bn - 1 (1 ≤ bi ≤ 106)。

输出使序列增加所需的最小移动次数。

我为这个问题编写了以下代码:

#include <iostream>
using namespace std;
int main()
{
    long long int n,d,ci,i,s;
    s=0;
    cin>>n>>d;
    int a[n];
    for(ci=0;ci<n;ci++)
    {
        cin>>a[ci];
    }
    for(i=0;i<(n-1);i++)
    {
        while(a[i]>=a[i+1])
        {
          a[i+1]+=d;
          s+=1;
        }
    }
    cout<<s;
    return 0;
}

效果很好。但在测试代码强制服务器中输入 2000 数字。时间限制为 1 秒。但它最多计算 1 秒。如何使此代码更短以更快地计算?

可以进行的一项改进是使用

std::ios_base::sync_with_stdio(false);

默认情况下,cin/cout 会浪费时间将自身与 C 库的 stdio 缓冲区同步,以便您可以自由地将对 scanf/printf 的调用与 cin/cout 上的操作混合在一起。通过使用上述调用关闭此功能,上述程序中的输入和输出操作应该花费更少的时间,因为它不再初始化输入和输出的同步。

众所周知,这在以前的代码挑战中有所帮助,这些挑战要求代码在特定的时间范围内完成,并且 c++ 输入/输出导致速度出现一些瓶颈。

你可以摆脱while循环。您的程序应该运行得更快,没有

#include <iostream>
using namespace std;
int main()
{
    long int n,d,ci,i,s;
    s=0;
    cin>>n>>d;
    int a[n];
    for(ci=0;ci<n;ci++)
    {
        cin>>a[ci];
    }
    for(i=0;i<(n-1);i++)
    {
        if(a[i]>=a[i+1])
        {
          int x = ((a[i] - a[i+1])/d) + 1; 
          s+=x;
          a[i+1]+=x*d;
        }
    }
    cout<<s;
    return 0;
}

这不是一个完整的答案,而是一个提示。

假设我们的顺序是 {1000000, 1}d是 2。

为了增加序列,我们需要使第二个元素 1,000,001 或更大。

我们可以按照你的方式做,反复添加 2 直到我们超过 1,000,000

1 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + ...

这需要一段时间,或者我们可以说

  • 我们的目标是 1,000,001
  • 我们有 1
  • 差额为 1,000,000
  • 所以我们需要做 1,000,000/2 = 500,000 次加法

所以答案是50万。

这要快得多,因为我们只做了 1 次加法 (1,000,000 + 1)、一次减法 (1,000,001 - 1) 和一个除法 (1,000,000/2),而不是做五十万次加法。

正如@molbdnilo所说,用数学来摆脱循环,这很简单。这是我的代码,被Codeforce接受。

#include <iostream>
using namespace std;
int main()
{
    int n = 0 , b = 0;
    int a[2001];
    cin >> n >> b;
    for(int i = 0 ; i < n ; i++){
        cin >> a[i];
    }
    int sum = 0;
    for(int i = 0 ; i < n - 1 ; i++){
        if(a[i] >= a[i + 1]){
            int minus = a[i] - a[i+1];
            int diff = minus / b + 1;
            a[i+1] += diff * b;
            sum += diff;
        }
    }
    cout << sum << endl;
    return 0;
}

我建议你分析你的代码,看看瓶颈在哪里。

浪费时间的热门领域之一是输入。 输入请求越少,程序的速度就越快。

因此,您可以通过从cin读取read()到缓冲区中,然后使用 istringstream 解析缓冲区来加快程序速度。

其他技术包括循环展开优化数据缓存。 减少分支或if语句的数量也将加快程序速度。 处理器更喜欢处理数据和移动数据,而不是跳转到代码中的不同区域。