Codeforces Round #632 (Div. 2) D - Challenges in school №41
一道模拟题,两人转头可以看成是把两人换过来或者是方向向右的人往右边前进了一步,统计最多步数,然后从尽可能多开始动,后边再一个一个动就行,重点只在于怎么维护可动的位置
原题链接:http://codeforces.com/contest/1333/problem/D
从本次top1大佬那学到了些C++11的遍历骚操作orz
AC代码
#include<iostream> #include<vector> #include<set> using namespace std; const int Maxn = 3e3 + 10; char s[Maxn]; int main() { ios::sync_with_stdio(false); int n, K; cin >> n >> K; cin >> (s + 1); int numInvertion = 0; int pre = 0; set<int> op; for (int i = n; i >= 1; i--) { if (s[i] == 'R') { if (s[i + 1] == 'L') op.insert(i); numInvertion += n - i - pre; pre++; } } if (K > numInvertion) { cout << -1; return 0; } vector<vector<int> > ans(K); for (int k = 0; k < K; k++) { auto it = op.begin(); while (it != op.end() && numInvertion >= K - k) { ans[k].push_back(*it); numInvertion--; it++; } op.erase(op.begin(), it); for (int i : ans[k]) swap(s[i], s[i + 1]); for (int i : ans[k]) { if (s[i - 1] == 'R') op.insert(i - 1); if (s[i + 2] == 'L') op.insert(i + 1); } } if (numInvertion) { cout << -1; return 0; } for (int k = 0; k < K; k++) { cout << ans[k].size() << " "; for (int i : ans[k]) cout << i << " "; cout << '\n'; } return 0; }