题目分析:首先数列长度为n,且为1~n中不重复的数字,也就意味着每个数字必须出现且只出现一次。首先,记录下输入中已经出现过的数字,再找出还未出现的数字,通过对未出现的数字进行全排列,再插入到原数组中,将原数组中的0替代掉,然后对替代后的数组进行判断,暴力计算合格排列为K的数列个数。代码如下
#include <iostream>
#include <algorithm>
#include <vector>
const int N = 100;
int vis[N];
using namespace std;
int isOk(int *num,int *queshi, int n,int k)
{
int tmp[N], acc = 0;
for (int i = 1, j = 1; i <= n; i++) //构建新数组,将原数组中的0替代
{
if (num[i] == 0)
{
tmp[i] = queshi[j++];
}
else{
tmp[i] = num[i];
}
//printf("%d ",tmp[i]);
}
for (int i = 1; i<=n - 1; i++) //对新数组进行暴力判断合法排列数目
{
for (int j = i + 1; j<=n; j++)
{
if (tmp[i]<tmp[j])
acc++;
}
}
if (acc == k)
return 1;
else
return 0;
}
void permutation(int *queshi, int *num, int n, int len, int index, int k, int &count )
{
//对数组queshi全排列
if (index > len){//全排列结束
for (int i = 1; i <= len; i++)
{
cout << queshi[i];
}
cout << endl;
if (isOk(num, queshi,n,k) == 1)
{
count++;
}
}
else
for (int i = index; i<=len; ++i){
//将第i个元素交换至当前index下标处
swap(queshi[index], queshi[i]);
//以递归的方式对剩下元素进行全排列
permutation(queshi, num, n, len, index + 1, k,count);
//将第i个元素交换回原处
swap(queshi[index], queshi[i]);
}
}
int main()
{
int n, k;
cin >> n >> k;
int temp;
int count = 0;
int num[N];
int zero = 0;
for (int i = 0; i <= n; i++){
vis[i] = 0;
}
for (int i = 1; i <= n; i++)
{
cin >> temp;
num[i] = temp;
vis[temp] = 1; //记录已经出现的数字
if (temp == 0)
zero++; //记录0的个数,同时也是数组queshi的范围1~zero
}
int queshi[N];
int v = 1;
for (int i = 1; i <= n; i++)
{
if (vis[i] == 0)
{
queshi[v++] = i; //记录没有出现的数字
}
}
///cout << zero;
permutation(queshi,num, n, zero,1, k,count);
cout << count << endl;
//cout << count << endl;
system("pause");
}