数据规模:n ≤ 2×106 / 时限:1s
题解
其实这道题类同一个哈密顿回路。
可知n为奇数且n不为1时是无解的,所以可特判输出-1。证明:因为n为奇数时0的唯一入边是int(n / 2),但n-1的唯一入边也是int(n / 2),所以无合法方案。
特判完n为不为1的奇数后,对于剩下的情况:
首先dfs + 回溯可计算到n为220,之后便会tle。
ac做法:直接dfs一遍即可,标记不用回溯,这样每个点都只会尝试两次(第二次直接返回)。
Code
//TLE
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e6+2;
#define _ ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int a[MAXN], book[MAXN], n, y;
void qqq() {
for (int i = 1; i <= n; i++)
cout << a[i] << ' ';
cout << "0" << "\n";
}
void dfs(int k, int num) {
if (num !=1 && k == 0) {
if (num == n+1) {
qqq();
exit(0);
}
else return;
}
if(!book[(2*k)%n]) {
book[(2*k)%n] = 1;
a[++num] = (2*k)%n;
dfs((k*2)%n, num);
book[(2*k)%n] = 0;
num--;
}
if (!book[(k*2+1)%n]) {
book[(k*2+1)%n] = 1;
a[++num] = (k*2+1)%n;
dfs((k*2+1)%n, num);
book[(k*2+1)%n] = 0;
num--;
}
}
int main()
{_
cin >> n;
if (n & 1 && n != 1) cout << "-1\n";
else {
a[1] = 0;
dfs(0, 1);
}
return 0;
}
//AC
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e6+2;
#define _ ios::sync_with_stdio(false);cin.tie(0);
int book[MAXN], n;
stack<int>ans;
void dfs(int k) {
if (book[k]) return;
book[k] = 1;
dfs((k * 2) % n);
dfs((k * 2 + 1) % n);
ans.push(k); //最后返回是倒着存进去的,这里用栈存方便结果的输出
}
int main()
{_
cin >> n;
if (n == 1) { puts("0 0"); exit(0); }
if (n & 1) cout << "-1\n";
else {
dfs(0);
while (!ans.empty()) {
cout << ans.top() << ' ';
ans.pop();
}
cout << "0\n" << endl;
}
return 0;
}