CF804E The same permutation 题解
构造小题,需要打表观察,没有上一道题目神秘。
有一个经典性质是交换两个位置的数字逆序对个数奇偶性改变,容易发现当\(n \equiv2,3 \pmod 4\)
然后直接分类讨论。
当\(n \equiv 0 \pmod 4\)的时候,每\(4\)个分为一组,同一组内的交换为(相当于\(n==4\)的顺序):
(1,2),(3,4),(1,4),(2,3),(1,3),(2,4).
不同组的交换为:
(1,5),(2,6),(1,6),(2,5),(1,7),(2,8),(1,8),(2,7),(3,5),(4,6),(3,6),(4,5),(3,7),(4,8),(3,8),(4,7).
如果说\(n \equiv 1 \pmod 4\),那么相当于比上头多了一个数,我们考虑把组内交换改一下(相当于\(n==5\)的顺序)
(1,n),(1,2),(2,n),(3,n),(3,4),(4,n),(1,4),(2,3),(1,3),(2,4).
这样就完成了。
代码:
#include <bits/stdc++.h>
using namespace std;
int n,d1,d2,d3,d4,v1,v2,v3,v4;
void solve(int q){
q--;d1=4*q+1;d2=4*q+2;d3=4*q+3;d4=4*q+4;printf("%d %d\n",d1,d2);printf("%d %d\n",d3,d4);
printf("%d %d\n",d1,d4);printf("%d %d\n",d2,d3);printf("%d %d\n",d1,d3);printf("%d %d\n",d2,d4);
return;
}
void solves(int q){
q--;d1=4*q+1;d2=4*q+2;d3=4*q+3;d4=4*q+4;
printf("%d %d\n",d1,n),printf("%d %d\n",d1,d2),printf("%d %d\n",d2,n);
printf("%d %d\n",d3,n),printf("%d %d\n",d3,d4),printf("%d %d\n",d4,n);
printf("%d %d\n",d1,d4);printf("%d %d\n",d2,d3);printf("%d %d\n",d1,d3);printf("%d %d\n",d2,d4);
return;
}
void calc(int q,int w){
q--;d1=4*q+1;d2=4*q+2;d3=4*q+3;d4=4*q+4;w--;v1=4*w+1;v2=4*w+2;v3=4*w+3;v4=4*w+4;
printf("%d %d\n",d1,v1);printf("%d %d\n",d2,v2);printf("%d %d\n",d1,v2);printf("%d %d\n",d2,v1);
printf("%d %d\n",d1,v3);printf("%d %d\n",d2,v4);printf("%d %d\n",d1,v4);printf("%d %d\n",d2,v3);
printf("%d %d\n",d3,v1);printf("%d %d\n",d4,v2);printf("%d %d\n",d3,v2);printf("%d %d\n",d4,v1);
printf("%d %d\n",d3,v3);printf("%d %d\n",d4,v4);printf("%d %d\n",d3,v4);printf("%d %d\n",d4,v3);
return;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
if(n%4==2||n%4==3){
cout<<"NO";
return 0;
}
cout<<"YES\n";
if(n%4==0){
for(int i=1;i<=n/4;i++){
solve(i);
}
}
else{
for(int i=1;i<=n/4;i++){
solves(i);
}
}
for(int i=1;i<=n/4;i++){
for(int j=i+1;j<=n/4;j++){
calc(i,j);
}
}
return 0;
}