牛牛的作業薄上有乙個長度為 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 個)。
輸出描述:
輸出一行表示合法的排列數目。
輸入例子:
5 5
4 0 0 2 0
輸出例子:
2
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
const
int maxn = 100 + 3;
int a[maxn]; //存放的原始資料
int b[12]; //存放未知的位置資料
int c[maxn]; //b每個排列放到對應的位置的順序對
int n,k;
//自己實現的全排列
void perm(int a,int l,int r)
printf("\n");
}else
}}int findnum(int s,int len)
int main()
for(int i=1;i<=n;i++)
int ans=0;
do }
if(findnum(c,n)==k) ans++;
}while(next_permutation(b,b+len));
printf("%d\n",ans);
return
0;}
但是這樣的時間複雜度是10!*100*50,應該會超時的,不過居然ac了。
然後發現可以通過預處理和分段計算的方法,把時間複雜度降低為10!*55;
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
const
int maxn = 100 + 3;
int a[maxn]; //存放的原始資料
int b[12]; //存放未知的位置資料
int c[maxn]; //b每個排列放到對應的位置的順序對
int d[maxn]; //存放已知的位置資料
int n,k;
int below[12][maxn];
int up[12][maxn];
int findnum(int s,int len)
int main()
for(int i=1;i<=n;i++)
//預處理,找出比b[i]在第i個位置時,左邊比它小的個數,右邊比它大的個數
for(int i=0;iint num=0,t=0;
for(int j=0;jif(a[j]!=0)
}num=0;
t=len1-1;
for(int j=n-1;j>=0;j--)
}else}}
int ans=0;
int tmp=findnum(d,len2);
//結果為未知的序列對個數+已知的位置序列對個數+未知的與已知的序列對個數
do while(next_permutation(b,b+len1));
printf("%d\n",ans);
return
0;}
演算法題 數列還原
牛牛的作業薄上有乙個長度為 n 的排列 a,這個排列包含了從1到n的n個數,但是因為一些原因,其中有一些位置 不超過 10 個 看不清了,但是牛牛記得這個數列順序對的數量是 k,順序對是指滿足 i j 且 a i a j 的對數,請幫助牛牛計算出,符合這個要求的合法排列的數目。輸入描述 每個輸入包含...
網易程式設計(數列還原)
牛牛的作業薄上有乙個長度為 n 的排列 a,這個排列包含了從1到n的n個數,但是因為一些原因,其中有一些位置 不超過 10 個 看不清了,但是牛牛記得這個數列順序對的數量是 k,順序對是指滿足 i j 且 a i a j 的對數,請幫助牛牛計算出,符合這個要求的合法排列的數目。輸入描述 每個輸入包含...
(百題程式設計)64 乘式還原
題目 a代表數字0到9中的前五個數字,z代表後五個數字,請還原下列乘式。a z a a a z a a a a a a z z z a a z a z a a 題目 a代表數字0到9中的前五個數字,z代表後五個數字,請還原下列乘式。a z a a a z a a a a a a z z z a a ...