| ||||||||||
Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
O(n) 解法,关键在于判环与映射。Key 是单射,所以规则对应了若干个环(如 key 为 {3, 2, 1} 时候(1-base),对于下标 1 的元素来说,第 1 次移动到下标 3,第 2 次移动到下标 1,故这个环长度为 2;相对地,下标 2 的元素所在的环是一个长度为 1 的自环)。找出这些环,并规定好原下标对应的位置(映射),即可在生成答案串时,对于某一 idx ,通过 (映射位置 + 环长) % k 得到最终位置,具体操作可参考如下代码: ```core code (cpp) struct rule { rule(int size) : size(size), id(size), offset(size) {} std::vector<std::vector<int> > loops; std::vector<int> id; // id[i]: the i-th elem is in id[i]-th loop std::vector<int> offset; // offset[i]: the i-th elem is at offset[i] in loop int size; }; rule get_rule(std::vector<int>& key) { const int N = key.size(); std::vector<bool> vis(N); rule res(N); for (int i = 0; i < N; i++) { if (vis[i]) continue; std::vector<int> loop; for (int p = i; !vis[p]; p = key[p]) { vis[p] = true; loop.push_back(p); } for (int j = 0; j < loop.size(); j++) { res.id[loop[j]] = res.loops.size(); res.offset[loop[j]] = j; } // res.loops.emplace_back(loop); res.loops.push_back(loop); } return res; } std::string encode(const rule& R, int k, std::string& s) { while (s.length() < R.size) s += ' '; std::string res(R.size, ' '); for (int i = 0; i < R.size; i++) { const std::vector<int>& loop = R.loops[R.id[i]]; res[loop[(R.offset[i] + k) % loop.size()]] = s[i]; } return res; } void solve(const rule& R) { int k; std::string s; while (true) { std::cin >> k; if (k == 0) return; std::cin.get(); std::getline(std::cin, s); std::cout << encode(R, k, s) << "\n"; } } int main() { for (int n; ; ) { std::cin >> n; if (n == 0) break; std::vector<int> key(n); for (int i = 0; i < n; i++) { std::cin >> key[i]; key[i]--; } rule r = get_rule(key); solve(r); std::cout << "\n"; } return 0; } ``` Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator