自動添字ガチャ(C++版)
概要
マーカーを付けた箇所それぞれで -1, ±0, +1 の 3 通りずらすことを自動で試し、望む結果が得られたものを出力してくれます。コードは全部 Gemini 3 が書いてくれました。
例題
アルゴリズムと数学 演習問題集 038 - How Many Guests?
解法
累積和の練習問題のようです。うろ覚えで書いてみたところ以下のようなコードになりました:
code:main.cpp
int main() {
int n, q;
std::cin >> n >> q;
std::vector<int> a(n);
for (int i = 0; i < n; i++) {
std::cin >> a.at(i);
}
std::vector<int> acc(n);
for (int i = 0; i < n; i++) {
acc.at(i + 1) = acc.at(i) + a.at(i);
}
for (int j = 0; j < q; j++) {
int l, r;
std::cin >> l >> r;
std::cout << acc.at(r) - acc.at(l) << std::endl;
}
}
サンプルを試すとなんかよくわからないエラーが出ます。
たぶん添字周りでミスったのでしょう。
そこで、テンプレの run_logic 内にコードをそのまま貼り付け、std::cin を in、std::cout を out にそれぞれ変更し、ズレが怪しい箇所を G() で囲みます。
さらにサンプルを in01.txt, out01.txt に保存し、solve_gacha(load_test_cases()) を実行します:
code:run_logic.cpp
void run_logic(std::istream& in, std::ostream& out, std::map<int, int>& current_offsets, std::set<int>& ids) {
int n, q;
in >> n >> q;
std::vector<int> a(n);
for (int i = 0; i < n; i++) {
// 配列外参照したときに例外を投げるため [] ではなく .at() を使う。
in >> a.at(i);
}
std::vector<int> acc(G(n));
for (int i = 0; i < G(n); i++) {
acc.at(i + 1) = acc.at(i) + a.at(G(i));
}
for (int j = 0; j < q; j++) {
int l, r;
in >> l >> r;
// 行番号をマーカーにしているので改行が必要。
out << acc.at(G(r))
- acc.at(G(l)) << std::endl;
}
}
code:in01.txt
10 5
8 6 9 1 2 1 10 100 1000 10000
2 3
1 4
3 9
6 8
1 10
code:out01.txt
15
24
1123
111
11137
すると次のような出力が得られます:
code:output.txt
// Loaded 1 test cases.
// Searching 5 points... (3^5 = 243)
/* Solution #1 */
std::map<int, int> best_offsets = {
{53, 1}, // Line 53
{55, 0}, // Line 55
{56, 0}, // Line 56
{64, 0}, // Line 64
{65, -1}, // Line 65
};
後は best_offsets をテンプレ内の指定された箇所に貼り付けて提出すれば AC が得られます。
提出
C++ (99 ms)
他の使用例
競技プログラミングの鉄則 演習問題集 A58 - RMQ (Range Maximum Queries)
ACL も少し改造すれば利用できます。
*.hpp 内の assert を全て my_assert に置換して、ファイルの頭に以下のコードを追加しましょう:
code:my_assert.hpp
#ifndef NDEBUG
#define my_assert(expr) \
if (!(expr)) { \
throw std::out_of_range("ACL Assertion Failed: " #expr " at " __FILE__ ":" + std::to_string(__LINE__)); \
}
#else
#define my_assert(expr) ((void)0)
#endif
これでミスっても実行時エラーを吐いて落ちるのではなく例外を投げてくれるのでガチャ失敗と判定されます。
元ポスト
#邪道テク