我是新的c ++学员。我登录了Codeforces网站,这是一个问题: 如果ai-1 <1,则将序列a0,a1,...,at-1称为增加。每个i的ai:0&lt; I&LT;吨。
给定序列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秒。 如何缩短此代码以更快地计算?
答案 0 :(得分:2)
可以做的一个改进是使用
std::ios_base::sync_with_stdio(false);
默认情况下,cin / cout浪费时间与C库的stdio缓冲区同步,这样你就可以自由地将对scanf / printf的调用与cin / cout上的操作混合。通过使用上述调用将其关闭,上述程序中的输入和输出操作应该花费更少的时间,因为它不再初始化输入和输出的同步。
众所周知,这有助于以前的代码挑战,这些挑战要求代码在特定时间范围内完成,而c ++输入/输出导致速度出现瓶颈。
答案 1 :(得分:1)
这不是一个完整的答案,而是一个提示。
假设我们的序列为{1000000, 1}
且d
为2。
为了增加序列,我们需要使第二个元素为1,000,001或更大。
我们可以通过重复添加2直到我们超过1,000,000
来实现1 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + ...
需要一段时间,或者我们可以说
所以答案是500,000。
这要快得多,因为我们只做了1次加法(1,000,000 + 1),1次减法(1,000,001 - 1)和1次除法(1,000,000 / 2),而不是做了50万次加法。
答案 2 :(得分:1)
你可以摆脱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;
}
答案 3 :(得分:0)
正如@molbdnilo所说,使用数学来摆脱循环,这很简单。 这是我在Codeforces上接受的代码。
#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;
}
答案 4 :(得分:0)
我建议您个人资料您的代码,以了解瓶颈所在。
浪费时间的一个热门领域是输入。输入请求越少,程序就越快。
因此,您可以通过使用cin
将read()
读入缓冲区来加速您的程序,然后使用istringstream
解析缓冲区。
其他技术包括循环展开和优化数据缓存。减少分支或if
语句的数量也将加快您的程序。处理器更喜欢处理数据并移动数据以跳转到代码中的不同区域。