実行時間制限: 2 sec / メモリ制限: 1024 MB / Difficulty: 223
問題概要
0
, 1
のみからなる長さ の文字列
が与えられる。
の中で先頭から
番目の
1
の塊を、 番目の
1
の塊の直後まで移動した文字列を出力せよ。なお、 には
1
の塊が 個以上含まれることが保証される。
制約
考察
まずは0
の塊と1
の塊をデータとして持っておきたい。こういうときはランレングス圧縮が有効だ。pair<char, int>
の配列のデータ構造に、それぞれの塊の大きさ (長さ?) を格納できる。
その後、0
の塊と1
の塊は互いに隣接している (どちらか一方が連続することはない) ことを利用して、先頭から 個目の
1
の塊とその直前の0
の塊の位置をswap
する。
あとは先頭から順に出力していけばよい。
コード
#include <bits/stdc++.h> using namespace std; #define rep(i, start, end) for (auto i = (start); (i) < (end); (i)++) // ======================================== // std::vector<std::pair<char, int>> encode(const std::string &str) { int n = (int)str.size(); std::vector<std::pair<char, int>> res; for (int l = 0; l < n;) { int r = l + 1; for (; r < n && str[l] == str[r]; r++) { }; res.push_back({str[l], r - l}); l = r; } return res; } int main() { int N, K; string S; cin >> N >> K >> S; vector<pair<char, int>> rle = encode(S); int cnt = 0, idx = 0; while (cnt != K - 1) { if (rle[idx].first == '1') cnt++; idx++; } swap(rle[idx], rle[idx + 1]); for (auto &&p : rle) { rep(i, 0, p.second) { cout << p.first; } } cout << endl; }
実装時間: 35分