A - フリーランスの報酬 / Freelance Compensation 解説 by admin
gpt-5.5-high概要
\(M\) 日以内に納品が完了する案件だけを対象に報酬を合計し、そこから手数料 \(P\%\) を差し引いた金額を求める問題です。
考察
案件 \(i\) が \(M\) 日以内に完了する条件は、納品までの日数 \(D_i\) が
\(D_i \leq M\)
を満たすことです。
したがって、すべての案件についてこの条件を確認し、条件を満たす案件の報酬 \(V_i\) だけを合計すればよいです。
たとえば、\(M = 10\) のとき、
| 案件 | \(D_i\) | \(V_i\) | 対象か |
|---|---|---|---|
| 1 | 5 | 1000 | 対象 |
| 2 | 12 | 2000 | 対象外 |
| 3 | 10 | 3000 | 対象 |
この場合、報酬の合計は
\(1000 + 3000 = 4000\)
です。
ここから手数料 \(P\%\) を引くので、実際に受け取る金額は
\(4000 \times \frac{100 - P}{100}\)
になります。
答えは小数点以下を切り捨てる必要がありますが、整数同士の割り算を使えば自然に切り捨てになります。
素朴な方法について
「1 日目から \(M\) 日目までシミュレーションする」ような方法を考えると、\(M\) は最大で \(10^9\) なので間に合いません。
しかし、この問題では各案件について「\(M\) 日以内に終わるか」だけが分かれば十分です。
そのため、日ごとのシミュレーションは不要で、案件を 1 つずつ見るだけで解けます。
アルゴリズム
- \(N, M, P\) を入力する。
- 報酬の合計を表す変数
sumを \(0\) で初期化する。 - 各案件について、\(D_i, V_i\) を入力する。
- \(D_i \leq M\) なら、その案件は \(M\) 日以内に完了するので、
sumに \(V_i\) を足す。 - 手数料を差し引いた金額を計算する。
具体的には、手数料を引いた後に残る割合は
\(100 - P\)
パーセントなので、答えは
\(sum \times \frac{100 - P}{100}\)
です。
整数で計算するため、実装では次のようにします。
\(ans = sum \times (100 - P) / 100\)
この割り算により、小数点以下は切り捨てられます。
計算量
- 時間計算量: \(O(N)\)
- 空間計算量: \(O(1)\)
実装のポイント
報酬の合計は最大で
\(2 \times 10^5 \times 10^6 = 2 \times 10^{11}\)
になるため、int では収まりません。
そのため、合計や計算結果には long long を使います。
また、手数料計算では
long long ans = sum * (100 - P) / 100;
のように先に掛け算をしてから割り算を行うことで、正しく小数点以下切り捨ての結果を得られます。
ソースコード
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
long long M;
long long P;
cin >> N >> M >> P;
long long sum = 0;
for (int i = 0; i < N; i++) {
long long D, V;
cin >> D >> V;
if (D <= M) sum += V;
}
long long ans = sum * (100 - P) / 100;
cout << ans << '\n';
return 0;
}
この解説は gpt-5.5-high によって生成されました。