题目描述
牛牛的作业薄上有一个长度为 n 的排列 A,这个排列包含了从1到n的n个数,但是因为一些原因,其中有一些位置(不超过 10
个)看不清了,但是牛牛记得这个数列顺序对的数量是 k,顺序对是指满足 i < j 且 A[i] < A[j] 的对数,请帮助牛牛计算出,符合这个要求的合法排列的数目。
输入描述:
每个输入包含一个测试用例。每个测试用例的第一行包含两个整数 n 和 k(1 <= n <= 100, 0 <= k <= 1000000000),接下来的 1 行,包含 n 个数字表示排列 A,其中等于0的项表示看不清的位置(不超过 10 个)。
输出描述:
输出一行表示合法的排列数目。
示例1
输入
5 5
4 0 0 2 0
输出
2
将还没有放进去的数进行全排列再依次放进去
#include<iostream>
#include<vector>
#include<set>
using namespace std;
int data1[105]; // 原始数据
vector<int> xiabiao; // 哪些位置没有加入数据
int data2[15];// 还没有加入的数据
int len;
int res = 0;
int n,k;
bool is_ok()
{
int cnt = 0;
for(int i = 0;i < n;i++)
for(int j = i + 1;j < n;j++)
{
if(data1[i] < data1[j])cnt++;
}
if(cnt == k)return true;
return false;
}
void quanpailie(int k)
{
if(k == len-1)
{
for(int i = 0;i < len;i++)
{
data1[xiabiao[i]] = data2[i];
}
if(is_ok())res++;
}
else
{
for(int j = k;j <= len-1;j++)
{
swap(data2[j],data2[k]);
quanpailie(k+1);
swap(data2[j],data2[k]);
}
}
}
int main()
{
int temp;
cin >> n >> k;
set<int>data; // 还没有加入的数据
for(int i = 1;i <= n;i++)data.insert(i);
for(int i = 0;i < n;i++)
{
cin >> data1[i];
if(data1[i] == 0)xiabiao.push_back(i); // 记录没有放入数据的下标
data.erase(data1[i]);
}
int i = 0;
set<int>::iterator it = data.begin();
for(;it != data.end();it++) data2[i++] = *it;
len = xiabiao.size(); // 还没有放进去的个数
quanpailie(0);
cout << res;
}