CF1095D Circular Dance 题解
Circular Dance
题目大意
现在有一个有 \(n\) 个数的环,已知每一个数后面的两个数(顺序未知),还原这个环。
思路
既然是个环,那么开头是几都可以,不妨设开头是一。
那么第二、第三个数必然只有两种选择。
设第二个数为 \(a_{1,0}\),第三个数为 \(a_{1,1}\)(我比较喜欢下标为0)
设第二个数为 \(x\),第三数为 \(y\),如果 \(a_{x,0} \ne y\) 并且 \(a_{x,1} \ne y\),证明两数顺序排反了,则将其交换
前三数都推导好了,后面的数就轻松了。
给个公式:\(p_i=a_{i-2,0} + a_{i-2,1}-p_{i-1}(i>3)\)
可以自己推一推。
代码
点击查看代码
#include <iostream>
using namespace std;
const int N = 200010;
int a[N][2];
int p[N];
int n, t;
int main(){
cin >> n;
for (int i = 1; i <= n; i++){
cin >> a[i][0] >> a[i][1]; // 读入不说话
}
p[1] = 1; // 设第一个数为1
p[2] = a[1][0];
p[3] = a[1][1];
if(p[3] != a[p[2]][0] && p[3] != a[p[2]][1]){ // 先处理好第二第三个数
swap(p[2], p[3]);
}
for (int i = 4; i <= n; i++){
p[i] = a[p[i - 2]][0] + a[p[i - 2]][1] - p[i - 1]; // 公式
}
for (int i = 1; i <= n; i++){
cout << p[i] << ' ';
}
return 0; // 完美结束
}