CodeForces 804E. The same permutation

Seyyed and MoJaK are friends of Sajjad. Sajjad likes a permutation. Seyyed wants to change the permutation in a way that Sajjad won't like it. Seyyed thinks more swaps yield more probability to do that, so he makes MoJaK to perform a swap between every pair of positions (i, j), where i < j, exactly once. MoJaK doesn't like to upset Sajjad.

Given the permutation, determine whether it is possible to swap all pairs of positions so that the permutation stays the same. If it is possible find how to do that.

Input

The first line contains single integer n (1 ≤ n ≤ 1000) — the size of the permutation.

As the permutation is not important, you can consider ai = i, where the permutation is a1, a2, ..., an.

Output

If it is not possible to swap all pairs of positions so that the permutation stays the same, print "NO",

Otherwise print "YES", then print  lines: the i-th of these lines should contain two integers a and b (a < b) — the positions where the i-th swap is performed.

Examples
input
3
output
NO
input
1
output
YES

题意:有一个排列p,把所有点对(i, j)(i < j)提取出来,用每个点对恰好一次,swap(p_i, p_j),使最后p和原来相同

题解:

首先我们证明交换次数必须是偶数

考虑一次交换可以拆成奇数次相邻的数的交换,一个相邻的交换逆序对数奇偶性会改变

因此C(n, 2) % 2 = 0,故n % 4 = 0或1

这提示我们按照4分组,然后构造

具体见代码

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define fill( x, y ) memset( x, y, sizeof x )
#define copy( x, y ) memcpy( x, y, sizeof x )
using namespace std;

typedef long long LL;
typedef pair < int, int > pa;

inline int read()
{
	int sc = 0, f = 1; char ch = getchar();
	while( ch < '0' || ch > '9' ) { if( ch == '-' ) f = -1; ch = getchar(); }
	while( ch >= '0' && ch <= '9' ) sc = sc * 10 + ch - '0', ch = getchar();
	return sc * f;
}

int main()
{
#ifdef wxh010910
	freopen( "data.in", "r", stdin );
#endif
	int n = read();
	if( n % 4 > 1 ) return puts( "NO" ), 0;
	puts( "YES" );
	for( int i = n % 4 ; i < n ; i += 4 )
	{
		for( int j = 0 ; j < i ; j++ ) printf( "%d %d\n", j + 1, i + 1 );
		printf( "%d %d\n", i + 1, i + 2 );
		for( int j = i - 1 ; ~j ; j-- ) printf( "%d %d\n", j + 1, i + 2 );
		for( int j = 0 ; j < i ; j++ ) printf( "%d %d\n", j + 1, i + 3 );
		printf( "%d %d\n", i + 3, i + 4 );
		for( int j = i - 1 ; ~j ; j-- ) printf( "%d %d\n", j + 1, i + 4 );
		printf( "%d %d\n", i + 1, i + 4 );
		printf( "%d %d\n", i + 2, i + 3 );
		printf( "%d %d\n", i + 1, i + 3 );
		printf( "%d %d\n", i + 2, i + 4 );
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值