元のタイトル:
分析は実現
これは数学の問題です。この関数の分析式が見つかれば、簡単に解けると考えるのは簡単です。コンピュータの強力な計算能力を使えば、問題をすばやく完了でき、この式を観察できますSub、an:の式を取得し、
1つずつ重ね合わせるので、次の解決策があります。
#include <iostream>
#include <cmath>
using namespace std;
long long solve(long long n,long long k)
{
long long num=0;
for (long long i=1;i<=n;i++)
num+=pow(-1,(i-1)/k+1)*i;
return num;
}
int main()
{
int T;
cin >> T;
long long n;
long long k;
while(T--)
{
cin >> n >> k;
cout << solve(n,k) << endl;
}
return 0;
}
ojレポートが失敗してタイムアウトになったのは残念です。考えてみてください。pow()関数は時間がかかるので、pow()関数を削除する方法を考えたので、最終的に次のコードを記述しました。
#include <iostream>
using namespace std;
long long solve(long long n,long long k)
{
long long num=0;
for(long long i=1;i<=n;i++)
{
if (((i-1)/k+1)%2!=0)
num+=(-i);
else
num+=i;
}
return num;
}
int main()
{
int T;
cin >> T;
long long n,k;
while(T--)
{
cin >> n >> k;
cout << solve(n,k) << endl;
}
return 0;
}
この方法の考え方は最初の方法と同じですが、pow関数が削除されており、今回は通過すると思いましたが、タイムアウト警告が再び出て、パフ、疲れました!実行する方法?もう一度考えてください。方法を変更できますか。
3番目の方法:
kを小さな期間、2kを大きな期間と見なすことができます。n/ 2kは大きな期間の数を表します。各大きな期間の値は、k * kとして簡単に知ることができます。前の部分の値がn / 2k * k ^ 2であり、結果の後に追加の部分があることは簡単にわかるので、別のコードを書くことができます。
#include <iostream>
using namespace std;
long long solve(long long n,long long k)
{
long long x=n/(2*k)*k*k;
long long a=n%(2*k),b=n-a+1;
if (n%(2*k)==0)
return x;
else if (a/(k+1)==0)
{
for (long long i=b;i<=n;i++)
x+=(-i);
return x;
}
else
{
for (long long i=b;i<b+k;i++)
x+=(-i);
for (long long i=b+k;i<=n;i++)
x+=i;
return x;
}
}
int main()
{
int T;
cin >> T;
long long n;
long long k;
while(T--)
{
cin >> n >> k;
cout << solve(n,k) << endl;
}
return 0;
}
はは、やっと合格!
ヒント:
この質問をするとき、私は最初にintで定義し、最後に範囲外を見つけました。そのため、ojを書くときにlong longを使用することに注意を払う必要があります!
ps:
これらの3つのコードはテストされ、すべて正しいですが、ojで実行すると、1と2の両方がタイムアウトし、3つだけが完全に通過できます。
参考になれば、去る前に「いいね!」をクリックしてみてください!