PTA 排列还原

2-3 排列还原 (25 分)

牛牛的作业簿上有一个长度为n的排列A[1...n],这个排列包含了从1到n的n个数,但是因为某种原因,其中有一些位置(不超过10个)看不清了,但是牛牛记得这个排列的顺序对的数量是k,顺序对是指满足i<j且A[i]<A[j]的对数。请帮助牛牛计算出符合要求的排列数目。输入n,k与序列A,返回可能的存在排列数目。

输入格式:

输入的第一行包含两个整数n和k(1≤n≤100,1≤k≤n(n−1)/2),接下来的一行,包含n个数字表示排列A,其中等于0的项表示看不清的位置(不超过10个)。

输出格式:

输出一行表示合法排列的数目。

输入样例:

5 5
4 0 0 2 0

输出样例:

2

 代码如下:

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
//数一数顺序对一共多少个
int countDui(vector<int>li) {
	int count = 0;
	for (int i = 0; i < li.size(); i++) {
		for (int j = i+1; j < li.size(); j++) {
			if (li[i] < li[j])		count++;
		}
	}
	return count;
}
int main() {
	int sum = 0; //记录多少种可能性
	int n, k;
	cin >> n >> k;
	int tt;
	vector<int> a;
	vector<int>t;
	for (int i = 0; i < n; i++) {
		cin >> tt;
		a.push_back(tt);
	}
	for (int i = 1; i <= n; i++) {
		if (find(a.begin(), a.end(),i) == a.end()) {
			t.push_back(i);//将看不见的数字放入t 在下一步排列组合所有情况
		}
	}
	do {
		vector<int>ab(a);
		int cnt = 0;
		for (int i = 0; i < t.size(); i++) {
			while (1) {
				if (ab[cnt] == 0) {
					ab[cnt] = t[i]; //将所有的排列组合放入放入原数组,看顺序对是否相等 相等即为一种可能性 
					break;
				}
				cnt++;
			}
		}
		if (countDui(ab) == k)	sum++;
	} while (next_permutation(t.begin(), t.end()));
	cout << sum << endl;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值