试题J:奇怪的回路(dfs)

试题J:奇怪的回路(dfs)_第1张图片
数据规模: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
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
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;
}

你可能感兴趣的:(搜索)