观察到以下规律:
如果一个n排列的第k<n位和最后一位交换,那么[0,n)依旧是一个排列,而[0,k]不是一个排列。
所以算法如下:
从一个n排列开始(如1 2 3 4 5 ... n)
对每个'0'的位置 i,总是找其后面的第一个'1'位置 j,交换perm[i],perm[j]。
#include <bits/stdc++.h> using namespace std; int main() { int n; string s; cin >> n >> s; vector<int> perm(n); int j=0; int i; for (i = 1; i <= n; i++) { perm[i - 1] = i; } bool flag = true; for (i = 0; i < s.size(); i++) { if (s[i] == '0') { if (i >= j) { // find next '1' after this '0' for (j = i + 1; j < n; j++) { if (s[j] == '1')break; } } if (j >= n) { flag = false; break; } swap(perm[i], perm[j]); } } if (flag) { for (i = 0; i < s.size() - 1; i++) cout << perm[i] << ' '; cout << perm[i]; } else { cout << -1; } } // 64 位输出请用 printf("%lld")