WOJ1269-Inversion

本文介绍了一种算法,用于寻找具有特定数量逆序对的最小排列。输入为整数n及逆序对数量m,输出是最小排列,使得该排列中恰好包含m个逆序对。文章详细阐述了如何通过确定特定阈值来构造这一排列,并提供了完整的C语言实现代码。

The inversion number of an integer sequence a1, a2, . . . , an is the number of pairs (ai, aj) that satisfy i < j and ai > aj . Given n and the inversion number m, your task is to find the smallest permutation of the set { 1, 2, . . . , n }, whose inversion number is exactly m.
A permutation a1, a2, . . . , an is smaller than b1, b2, . . . , bn if and only if there exists an integer k such that aj = bj for 1 <= j < k but ak < bk.

输入格式

The input consists of several test cases. Each line of the input contains two integers n and m. Both of the integers at the last line of the input is −1, which should not be processed. You may assume that 1 <= n <= 50000 and 0 <= m <= n(n − 1)/2.

输出格式

For each test case, print a line containing the smallest permutation as described above, separates the numbers by single spaces.

样例输入

5 9
7 3
-1 -1

样例输出

4 5 3 2 1
1 2 3 4 7 6 5


#include <stdio.h>
int n,m;
int main(){
	int i,j,sp;
	while(scanf("%d%d",&n,&m)==2) {
		if(n==-1&&m==-1) break;
		sp=1;
		while(sp*(sp-1)/2<m) sp++;
		int k=n-sp;
		for(i=1; i<=k; i++) printf("%d ",i);
		int first=m-(sp-1)*(sp-2)/2;
		printf("%d ",first+1+k);
		for(i=sp; i>1; i--) {
			if(i==first+1) continue;
			printf("%d ",i+k);
		}
		printf("%d\n",i+k);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值