2017校招-数列

题目描述

牛牛的作业薄上有一个长度为 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;
}

猜你喜欢

转载自blog.csdn.net/weixin_40936298/article/details/82781422