1. 程式人生 > >2017校招-數列

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;
}