EX21 - 計算量の見積もり
解説
/
実行時間制限: 2 sec / メモリ制限: 256 MB
問題文
次のプログラムではf0〜f5の6つの関数が定義されており、main関数から呼び出されています。 それぞれの関数の計算量を見積もって、最も計算時間のかかる関数を呼び出している行をコメントアウトしてください。
制限時間は2秒です。AtCoderのジャッジでは1秒あたり10^8回程度の計算が可能です。不正解だった場合
となります。制約を読み、各関数の実行時間を見積もりましょう。
プログラム
#include <bits/stdc++.h> using namespace std; int f0(int N) { return 1; } int f1(int N, int M) { int s = 0; for (int i = 0; i < N; i++) { s++; } for (int i = 0; i < M; i++) { s++; } return s; } int f2(int N) { int s = 0; for (int i = 0; i < N; i++) { int t = N; int cnt = 0; while (t > 0) { cnt++; t /= 2; } s += cnt; } return s; } int f3(int N) { int s = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { s++; } } return s; } int f4(int N) { int s = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { s += i + j; } } return s; } int f5(int N, int M) { int s = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { s += i + j; } } return s; } int main() { int N, M; cin >> N >> M; int a0 = -1, a1 = -1, a2 = -1, a3 = -1, a4 = -1, a5 = -1; // 計算量が最も大きいもの1つだけコメントアウトする a0 = f0(N); a1 = f1(N, M); a2 = f2(N); a3 = f3(N); a4 = f4(N); a5 = f5(N, M); cout << "f0: " << a0 << endl; cout << "f1: " << a1 << endl; cout << "f2: " << a2 << endl; cout << "f3: " << a3 << endl; cout << "f4: " << a4 << endl; cout << "f5: " << a5 << endl; }
制約
- 0 \leq N \leq 10^6
- 0 \leq M \leq 10^2
回答例
答え方の例です。
この例ではf0
の呼び出しをコメントアウトしていますが、f0
はO(1)なのでこの回答は不正解となります。
#include <bits/stdc++.h> using namespace std; int f0(int N) { return 1; } int f1(int N, int M) { int s = 0; for (int i = 0; i < N; i++) { s++; } for (int i = 0; i < M; i++) { s++; } return s; } int f2(int N) { int s = 0; for (int i = 0; i < N; i++) { int t = N; int cnt = 0; while (t > 0) { cnt++; t /= 2; } s += cnt; } return s; } int f3(int N) { int s = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { s++; } } return s; } int f4(int N) { int s = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { s += i + j; } } return s; } int f5(int N, int M) { int s = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { s += i + j; } } return s; } int main() { int N, M; cin >> N >> M; int a0 = -1, a1 = -1, a2 = -1, a3 = -1, a4 = -1, a5 = -1; // 計算量が最も大きいもの1つだけコメントアウトする // a0 = f0(N); a1 = f1(N, M); a2 = f2(N); a3 = f3(N); a4 = f4(N); a5 = f5(N, M); cout << "f0: " << a0 << endl; cout << "f1: " << a1 << endl; cout << "f2: " << a2 << endl; cout << "f3: " << a3 << endl; cout << "f4: " << a4 << endl; cout << "f5: " << a5 << endl; }
ヒント
クリックでヒントを開く
それぞれの関数の計算量を示します。
計算量 | |
---|---|
f0 |
O(1) |
f1 |
O(N+M) |
f2 |
O(N \log N) |
f3 |
O(1) |
f4 |
O(N^2) |
f5 |
O(NM) |
NとMの大きさを考えて実行時間が最も長いものを選びましょう。
テスト入出力
書いたプログラムがACにならず、原因がどうしてもわからないときだけ見てください。
クリックでテスト入出力を見る
テスト入力1
1000000 100
テスト出力1
f0: 1 f1: 1000100 f2: 20000000 f3: 9 f4: -1 f5: -1404227328
解答例
必ず自分で問題に挑戦してみてから見てください。
クリックで解答例を見る
#include <bits/stdc++.h> using namespace std; int f0(int N) { return 1; } int f1(int N, int M) { int s = 0; for (int i = 0; i < N; i++) { s++; } for (int i = 0; i < M; i++) { s++; } return s; } int f2(int N) { int s = 0; for (int i = 0; i < N; i++) { int t = N; int cnt = 0; while (t > 0) { cnt++; t /= 2; } s += cnt; } return s; } int f3(int N) { int s = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { s++; } } return s; } int f4(int N) { int s = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { s += i + j; } } return s; } int f5(int N, int M) { int s = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { s += i + j; } } return s; } int main() { int N, M; cin >> N >> M; int a0 = -1, a1 = -1, a2 = -1, a3 = -1, a4 = -1, a5 = -1; // 計算量が最も大きいもの1つだけコメントアウトする a0 = f0(N); a1 = f1(N, M); a2 = f2(N); a3 = f3(N); // a4 = f4(N); a5 = f5(N, M); cout << "f0: " << a0 << endl; cout << "f1: " << a1 << endl; cout << "f2: " << a2 << endl; cout << "f3: " << a3 << endl; cout << "f4: " << a4 << endl; cout << "f5: " << a5 << endl; }