每个输入包含一个测试用例。每个测试用例的第一行包含两个整数 n 和 k(1 <= n <= 100, 0 <= k <= 1000000000),接下来的 1 行,包含 n 个数字表示排列 A,其中等于0的项表示看不清的位置(不超过 10 个)。
输出一行表示合法的排列数目。
5 5 4 0 0 2 0
2
思路:首先将模糊的数字统计出来,并求出这些数字的全排列,然后对每个排列求顺序对
关键去求全排列,需要递归的求出所有排列。。。
ps:第一次做的时候没看清楚题,以为可以有重复数字,直接深搜计算了,结果。。。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
public class Main{
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
int RES = 0;
int n = sc.nextInt();
int k = sc.nextInt();
int[] A = new int[n];
boolean[] flag = new boolean[n+1];
//flag标记哪些数字已经存在
for(int i=0;i<n;i++){
A[i] = sc.nextInt();
if(A[i] != 0){
flag[A[i]] = true;
}
}
//统计排列中不存在的数字
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i=1;i<=n;i++){
if(flag[i] == false)
list.add(i);
}
//perm用来存模糊数字的全排列
List<ArrayList<Integer>> perm = new ArrayList<ArrayList<Integer>>();
//计算perm
calperm(perm, list, 0);
//统计已有的排列的顺序对
int cv = 0;
for(int i=0;i<n;i++){
if(A[i]!= 0){
for(int j=i+1;j<n;j++){
if(A[j] != 0 && A[i] < A[j])
cv++;
}
}
}
//计算每个模糊数字排列的顺序对,如果与k相等,则结果RES加一
for(ArrayList<Integer> tmp : perm){
int val = cv;
int[] tmpA = Arrays.copyOf(A, n);
val += calvalue(tmp, tmpA);
if(val == k)
RES++;
}
System.out.println(RES);
}
}
//计算排列的顺序对
public static int calvalue(List<Integer> list, int[] A){
int val = 0;
int j = 0;
for(int i=0;i<A.length;i++){
if(A[i] == 0){
A[i] = list.get(j++);
for(int k = 0;k<i;k++){
if(A[k]!=0 && A[k]<A[i])
val++;
}
for(int k=i+1;k<A.length;k++){
if(A[k]!=0 && A[k]>A[i])
val++;
}
}
}
return val;
}
//计算全排列
public static void calperm(List<ArrayList<Integer>> perm , ArrayList<Integer> list, int n){
if(n == list.size()){
perm.add(new ArrayList<Integer>(list));
}else{
for(int i=n;i<list.size();i++){
Collections.swap(list, i, n);
calperm(perm, list, n+1);
Collections.swap(list, i, n);
}
}
}
}
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <algorithm>
using namespace std;
typedef long long ll;
//http://www.nowcoder.com/questionTerminal/b698e67a2f5b450a824527e82ed7495d
int a[105];
bool appear[105];
int missidx[15];
int missnum[15];
int misscnt=0;
int smaller[105][105];
int larger[105][105];
int calc_orderedPairs(int *num,int n){
int ans=0;
for(int i=1;i<n;i++){
if(num[i])
for(int j=0;j<i;j++){
if(num[j]&&num[j]<num[i]){
++ans;
}
}
}
return ans;
}
int main(){
int n,k;
scanf("%d%d",&n,&k);
if(k>n*(n-1)/2){
puts("0");
return 0;
}
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
if(!a[i])missidx[misscnt++]=i;
else appear[a[i]]=1;
}
misscnt=0;
for(int i=1;i<=n;i++){
if(!appear[i]){
missnum[misscnt++]=i;
}
}
//given inner
int given=calc_orderedPairs(a,n);
if(given>k){
puts("0");
return 0;
}
//given and not given
for(int i=0;i<misscnt;++i){
int small=0,large=0;
for(int j=0;j<n;j++){
if(!a[j]){
smaller[j][missnum[i]]=small;
}
else if(a[j]<missnum[i])++small;
}
for(int j=n-1;j>=0;--j){
if(!a[j]){
larger[j][missnum[i]]=large;
}
else if(a[j]>missnum[i])++large;
}
}
int ans=0;
//not given
do{
int inner=calc_orderedPairs(missnum,misscnt);
for(int i=0;i<misscnt;++i){
inner+=smaller[missidx[i]][missnum[i]];
inner+=larger[missidx[i]][missnum[i]];
}
if(inner+given==k) ++ans;
}while(next_permutation(missnum,missnum+misscnt));
printf("%d\n",ans);
return 0;
}
#include<iostream>
#include<vector>
using namespace std;
bool find(vector<int> v,int n) //查询v中是否存在整数n
{
for(int i = 0;i<v.size();++i)
if(v[i]==n)
return true;
return false;
}
vector<vector<int>> pv; //全局变量
void Perm(vector<int> &v,int st) //对v中的数字进行全排列
{
if(st == v.size())
pv.push_back(v);
else
{
for(int i = st;i<v.size();++i)
{
swap(v[i],v[st]);
Perm(v,st+1);
swap(v[i],v[st]);
}
}
}
void change(vector<int> &v,vector<int> subv,vector<int> vpos)//将v中的0用全排之后的数字分别代替
{
for(int i = 0;i<vpos.size();++i)
v[vpos[i]] = subv[i];
}
int cal(vector<int> v) //计算顺序对的个数
{
int cnt = 0;
for(int i = 0;i<v.size()-1;++i)
for(int j = i+1;j<v.size();++j)
if(v[i]<v[j])
++cnt;
return cnt;
}
int main()
{
int n,k,tmp;
while(cin>>n>>k)
{
vector<int> v,subv,vpos;
for(int i = 0;i<n;++i)
{
cin>>tmp;
v.push_back(tmp);
}
for(int i = 0;i<v.size();++i)
if(v[i]==0)
vpos.push_back(i); //记录下vector<int>中0的位置
for(int i = 1;i<=n;++i)
if(!find(v,i))
subv.push_back(i);
Perm(subv,0);
vector<int> vcnt;
for(int i = 0;i<pv.size();++i)
{
change(v,pv[i],vpos);
vcnt.push_back(cal(v));
}
int vcntk = 0;
for(int i = 0;i<vcnt.size();++i)
if(vcnt[i]==k)
++vcntk;
cout<<vcntk<<endl;
}
return 0;
}
#include<stdio.h>
int a[20],tot=0,book[101],n,x[101],res=0,k,i,vis[20];
int getCnt(){
int i,j,res=0;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
if(x[i]<x[j]) res++;
return res;
}
void dfs(int step){
if(step==n){
if(getCnt()==k) res++;
return;
}
if(x[step]) dfs(step+1);
else
for(int i=0;i<tot;i++)
if(!vis[i]){
vis[i]=1,x[step]=a[i];
dfs(step+1);
vis[i]=0,x[step]=0;
}
}
int main(){
for(scanf("%d%d",&n,&k),i=0;i<n;i++)
scanf("%d",&x[i]),book[x[i]]=1;
for(i=1;i<=n;i++)
if(!book[i]) a[tot++]=i;
dfs(0);
printf("%d\n",res);
}
#include <iostream>
#include <algorithm>
using namespace std;
int main(void)
{
int n,k;
while(cin >> n >> k)
{
int *data = new int[n];
bool *flag0 = new bool[n];
int num0 = 0;
for(int i=0; i<n; i++)
{
cin >> data[i];
if(data[i] == 0) num0 ++, flag0[i] = true;
else flag0[i] = false;
}
int *data2 = new int[num0];
int pos = 0;
for(int i=1; i<=n; i++)
{
int j;
for(j=0; j<n; j++) if(data[j] == i) break;
if(j == n) data2[pos++] = i;
}
int num_k;
int result = 0;
do{
pos = 0;
num_k = 0;
for(int i=0; i<n; i++) if(flag0[i]) data[i] = data2[pos++];
for(int i=0; i<n; i++)
{
for(int j=i+1; j<n; j++) if(data[j] > data[i]) num_k ++;
}
if(num_k == k) result ++;
}while(next_permutation(data2,data2+num0));
cout << result << endl;
}
return 0;
}
def permutation(nums, p, q, candicates): if p == q: candicates.append(list(nums)) else: for i in range(p, q): nums[i], nums[p] = nums[p], nums[i] permutation(nums, p + 1, q, candicates) nums[i], nums[p] = nums[p], nums[i] def computePairs(nums): n, cnt = len(nums), 0 for i in range(n - 1): for j in range(i + 1, n): if nums[i] < nums[j]: cnt += 1 return cnt if __name__ == "__main__": n, k = map(int, input().split()) nums = list(map(int, input().split())) normal = [num for num in nums if num != 0] # 未缺失数字 missing = list(set(range(1, n + 1)) - set(normal)) # 缺失数字 missCnt = len(missing) candicates = [] permutation(missing, 0, missCnt, candicates) # 缺失数字的全排列 count = 0 for candicate in candicates: # 把缺失数字填入原数组 arr = list(nums) ptr = 0 for i in range(n): if nums[i] == 0: arr[i] = candicate[ptr] ptr += 1 else: arr[i] = nums[i] # 暴力计算顺序对 if computePairs(arr) == k: count += 1 print(count)
只通过了80%,有一处小错误,我实在找不出来了,思想是对的。找出缺少的数
字,将其全排序,然后在放回原数组中,判断该数组是否成立,成立加一
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner input=new Scanner(System.in);
while(input.hasNext()){
int n=input.nextInt();
int k=input.nextInt();
int[] a=new int[n];
for(int i=0; i<n; i++)
a[i]=input.nextInt();
boolean[] f=new boolean[n];
for(int i=0; i<n; i++){
if(a[i]!=0){
f[a[i]-1]=true;
}
}
TreeSet<String> arr=new TreeSet<>();
String s="";
for(int i=0; i<n; i++){
if(!f[i])
s+=String.valueOf(i+1);
}
arr.add(s);
isPiont(0,s.toCharArray(),arr);
int count=0;
for(String elem: arr){
int[] temp=new int[n];
int index=0;
for(int i=0; i<n; i++){
if(a[i]==0){
temp[i]=Integer.valueOf(String.valueOf(elem.charAt(index++)));
}else{
temp[i]=a[i];
}
}
if(isRight(k,n,temp))
count++;
}
System.out.println(count);
}
}
public static boolean isRight(int k, int n, int[] a){
int count=0;
for(int i=0; i<n-1; i++){
for(int j=i+1; j<n; j++){
if(a[i]<a[j])
count++;
}
}
if(count==k)
return true;
else
return false;
}
public static void isPiont(int start, char[] ch, TreeSet<String> arr){
if(start==ch.length-1){
arr.add(String.valueOf(ch));
return ;
}else{
for(int i=start; i<ch.length; i++){
swap(i, start, ch);
isPiont(start+1,ch,arr);
swap(i, start, ch);
}
}
}
public static void swap(int i, int j, char[] ch){
char temp=ch[i];
ch[i]=ch[j];
c***emp;
}
}
import itertools
list1 = input().split()
n = int(list1[0])
k = int(list1[1])
A = input().split()
B = []
for i in range(n):
B.append(int(A[i]))
zero_ind = []
not_zero = []
# 找出零的位置与非零元素的值
for i in range(n):
if B[i] == 0:
zero_ind.append(i)
else:
not_zero.append(i)
# 求出剩下需要填入数组的值
num_to_add = list(range(1,n+1))
for i in range(len(not_zero)):
num_to_add.remove(B[not_zero[i]]) #1
dict1 = {}
j = 0
# 排列
for i in itertools.permutations(num_to_add,len(num_to_add)):
dict1[j] = list(i)
j += 1
con_right = 0
# 填入数组与求顺序
for i in range(len(dict1)):
#i=0
test = dict1[i]
con = 0
for m in range(len(num_to_add)):
B.insert(zero_ind[m],test[m])
del B[zero_ind[m]+1]
for x in range(n):
for y in range(x+1,n):
if (B[x] < B[y]):
con += 1
if (con == k):
con_right += 1
print(con_right)
新手上路,python编写,欢迎大家指导
# -*- coding: utf8 -*-
import itertools
def get_ppair_num(a, n,dvalues):
"""
计算用dvalues替换a中对应0元,计算替换后的顺序对数
"""
idx = 0
count = 0
for i in range(n):
if a[i] == 0:
value = dvalues[idx]
idx += 1
else:
value = a[i]
idx0=0
for j in range(i):
if a[j]==0:
dv=dvalues[idx0]
idx0+=1
else:
dv=a[j]
if value > dv:
count += 1
return count
def count_permuations(a, n, k):
"""
枚举所有0元位置的一个全排列,统计每种顺序对数为k的排列
"""
count = 0
s = set(range(1, n + 1)) - set(a)
for dvalues in itertools.permutations(s):
ct=get_ppair_num(a, n,dvalues)
if ct==k:
count += 1
return count
n, k = map(int, raw_input().strip().split(' '))
a = map(int, raw_input().strip().split(' '))
print count_permuations(a, n, k)
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int n, k,totalLegal=0;
vector<int> A, B;
vector<int> indexRem, remainMat;
int calcK(vector<int> vec){
int count = 0;
for (int i = 0; i < vec.size(); i++){
for (int j = i + 1; j < vec.size(); j++){
if (vec[i] < vec[j]){
count++;
}
}
}
return count;
}
void allSort(vector<int> vec, int index){
if (index == vec.size()){
for (int i = 0; i < indexRem.size(); i++){
B[indexRem[i]] = vec[i];
}
if (k == calcK(B)){
totalLegal++;
}
return;
}
else{
for (int i = index; i < vec.size(); i++){
swap(vec[i], vec[index]);
allSort(vec, index + 1);
swap(vec[i], vec[index]);
}
}
}
int main(){
cin >> n>>k;
A=vector<int>(n, 0);
B = A;
for (int i = 0; i < n; i++){
A[i] = i + 1;
};
for (int j = 0; j < n; j++){
cin >> B[j];
}
//得到看不清索引的下标
for (int i = 0; i < n; i++){
if (B[i] != 0){
A[B[i]-1]=0;
}else{
indexRem.push_back(i);
}
}
//得到看不清的项
for (int i = 0; i < n; i++){
if (A[i] != 0){
remainMat.push_back(A[i]);
}
}
//得到缺失项的全排列
allSort(remainMat, 0);
cout << totalLegal << endl;
return 0;
}
有没有大佬能帮我看看我的代码,实在找不到问题出在哪。。。
case通过率为90.00%
测试用例:
100 2405
4 62 10 33 86 58 9 49 68 84 30 88 90 67 59 0 19 25 12 72 44 85 51 5 13 98 94 91 24 47 27 95 100 77 15 92 0 70 55 31 28 81 75 39 34 74 2 89 45 63 36 64 43 93 29 50 7 54 0 82 71 66 97 53 23 38 69 52 48 21 26 17 20 57 37 61 11 73 60 78 18 79 0 80 16 83 56 35 0 32 6 96 1 99 46 76 22 87 3 41
对应输出应该为:
1
你的输出为:
2
#include<stdio.h>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<stack>
#include<algorithm>
#include<climits>
#include<set>
using namespace std;
void process(vector<int> array, int n, int k)
{
set<int> sets;
for (int i = 0; i < n; i++)
{
if (array[i] != 0)
{
sets.insert(array[i]);
}
}
vector<int> num; //存放缺损元素
for (int i = 1; i < n + 1;i++)
{
if (sets.find(i) == sets.end())
{
num.push_back(i);
}
}
int res = 0;
vector<int> arr;
do
{
int index = 0;
int count = 0;
for (int i = 0; i < n; i++)
{
int cur = array[i] == 0 ? num[index++] : array[i];
arr.push_back(cur);
for (int j = 0;j < i;j++)
{
if (arr[j] < cur)
{
count++;
//cout << count << endl;
}
}
}
res += count == k ? 1 : 0;
} while (next_permutation(num.begin(), num.end()));
cout << res << endl;
}
int main()
{
int n, k;
cin >> n >> k;
vector<int> array(n, 0);
for (int i = 0; i < n;i++)
{
cin >> array[i];
}
process(array, n, k);
system("pause");
return 0;
}
//x的,这编辑工具真难用
//dfs枚举每一个组合,对于每一个组合都计算一次顺序数对个数,注意在枚举的是就可以计算,顺便可以剪枝
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static int ans = 0;
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int[] arr = lineToIntArray(br.readLine());
int n = arr[0], k = arr[1];
arr = lineToIntArray(br.readLine());
List<Integer> positions = new LinkedList<>();
Set<Integer> set = new HashSet<>();
for (int i = 0; i < n; i++) {
set.add(arr[i]);
if (arr[i] == 0) { positions.add(i); continue;}
for (int j = i + 1; j < n; j++) {
if (arr[j] == 0) continue;
if (arr[i] < arr[j]) k--;
}
}
List<Integer> loss = new LinkedList<>();
for (int i = 1; i <= n; i++) if (!set.contains(i)) loss.add(i);
dfs(arr, positions, k, loss, 0);
System.out.println(ans);
}
public static void dfs(int[] arr, List<Integer> positions, int k, List<Integer> number, int depth) {
if (k == 0 && number.size() == 0) {ans++; return;}
if (k < 0 || depth >= positions.size()) return;
int pos = positions.get(depth);
for (int i = 0; i < number.size(); i++) {
int num = number.remove(i);
arr[pos] = num;
dfs(arr, positions, k - countPair(arr, pos), number, depth + 1);
arr[pos] = 0;
number.add(i, num);
}
}
public static int countPair(int[] arr, int pos) {
int ans = 0;
for (int i = 0; i < pos; i++) {
if (arr[i] > 0 && arr[i] < arr[pos]) ans++;
}
for (int i = pos + 1; i < arr.length; i++) {
if (arr[i] > 0 && arr[pos] < arr[i]) ans++;
}
return ans;
}
public static int[] lineToIntArray(String line) {
String[] arr = line.trim().split(" ");
int[] ans = new int[arr.length];
for (int i = 0; i < arr.length; i++)
ans[i] = Integer.parseInt(arr[i]);
return ans;
}
public static int lineToInt(String line) {
return Integer.parseInt(line);
}
}
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int order(vector<int> vi){ int cnt=0; if(vi.size()>=2){ for(int i=vi.size()-1;i>=0;i--){ for(int j=0;j!=i;j++){ if(vi[i]>vi[j]) cnt++; } } } return cnt;
}
int main(){
int n,k;
while(cin>>n>>k){
int cnt=0;
vector<int> pst0;
vector<int> a(n,0);
vector<int> c; vector<bool> flag(n+1,false);
for(int i=0;i<a.size();i++){
cin>>a[i];
if(a[i]!=0){
flag[a[i]]=true; }else{ pst0.push_back(i); }
}
for(int i=1;i<flag.size();i++){
if(flag[i]==false){
c.push_back(i);
}
}
sort(c.begin(),c.end());
/* for(int i:c){
cout<<i<<" "; }cout<<endl; for(int i:pst0){ cout<<i<<" "; }cout<<endl;
*/ do{ int idx=0; for(int i=0;i<pst0.size();i++){ a[pst0[i]]=c[idx]; idx++; } int tmp=order(a);
/* for(int i:a){ cout<<i<<" "; }cout<<": "<<tmp<<endl;
*/ if(tmp==k) cnt++; }while(next_permutation(c.begin(),c.end())); cout<<cnt<<endl;
}
}
#include<iostream>
#include<vector>
#include<set>
#include <algorithm>
using namespace std;
int find_dui(int a[], int N){
int pairnum = 0;
for (int i = 0; i < N-1; ++i){
for (int j = i+1; j < N; ++j)
{
if (a[i] < a[j])
pairnum++;
}
}
return pairnum;
}
int main()
{
int N, K;
int num = 0;
cin >> N >> K;
int a[100];
vector <int> s;
vector<int> fuzpos;
vector<int> fuznum;
for (int i = 0; i < N; ++i)
{
cin >> a[i];
s.push_back(a[i]);
if (a[i] == 0)
fuzpos.push_back(i); // missing num position
}
for (int i = 1; i <= N; ++i)
if (find(s.begin(), s.end(), i) == s.end())
fuznum.push_back(i); // 没有出现过的数字
vector<int> ::iterator iter = fuznum.begin();
do
{
for (int k = 0; k < fuznum.size(); ++k)
a[fuzpos[k]] = fuznum[k];
if (find_dui(a, N) == K)
num++;
} while (next_permutation(iter, iter + fuznum.size())); // 取下一个排列组合
cout << num << endl;
}
用的最直接的方法遍历所有没出现数字的全排列,并将各种排列方式根据索引添加在0位置上 再遍历每一种的合法排序数目,与k相等计数器count++
import java.util.LinkedList;import java.util.List;import java.util.Scanner;public class Main{static List<List<Integer>> resultlist=new LinkedList<List<Integer>>();//最后得到各种组合的链表public static void main(String[] args) {Scanner scan=new Scanner(System.in);int n=scan.nextInt();int k=scan.nextInt();int []nums=new int[n];for (int i = 0; i < n; i++) {nums[i]=scan.nextInt();}int zeros=getzerocount(nums);List<Integer> list=getnums(nums);//存在的数字List<Integer> old_list=ArrayToList(nums);List<Integer> zero_index=getindexofzero(nums);//零索引的链表List<Integer> numbers=get_no_nums(nums);// System.out.print("oldList");printList(old_list);// System.out.print("zeroList");printList(zero_index);// System.out.print("list");printList(list);// System.out.print("numbers");printList(numbers);int x[]=new int[numbers.size()];for (int i = 0; i < x.length; i++) {x[i]=0;}dfs(ListtoArray(numbers), x);// System.out.print("oldList");printList(old_list);// System.out.print("zeroList");printList(zero_index);// System.out.print("list");printList(list);//System.out.println(resultlist.size());int count=0;for (int i = 0; i < resultlist.size(); i++) {//第几条返回记录List<Integer> new_list=old_list;List<Integer> eachlist=resultlist.get(i);for (int j = 0; j < zeros; j++) {new_list.set(zero_index.get(j), eachlist.get(j));}// printList(new_list);if(getcount(new_list)==k){count++;}}System.out.println(count);}private static int [] ListtoArray(List<Integer> list){int x[]=new int[list.size()];for (int i = 0; i < list.size(); i++) {x[i]=list.get(i);}return x;}private static List<Integer> getindexofzero(int a[]){//获得数字0位置的索引List<Integer> list=new LinkedList<Integer>();for (int i = 0; i < a.length; i++) {if(a[i]==0){list.add(i);}}return list;}@SuppressWarnings("null")private List<Integer> getUnuseNums(int nums[],int n){List<Integer> list=getnums(nums);List<Integer> list2=null;for (int i = 1; i <=n; i++) {if(list.contains(i)){continue;}else{list2.add(i);}}return list2;}private static int getzerocount(int []a){int n=a.length;return n-getnums(a).size();}private static void printList(List<Integer> list){for (int i=0;i<list.size();i++) {System.out.print(list.get(i)+" ");}System.out.println();}private static List<Integer> ArrayToList(int a[]){List<Integer> list=new LinkedList<Integer>();for (int i = 0; i < a.length; i++) {list.add(a[i]);}return list;}static int depth=0;private static void dfs(int numbers[],int [] list){if(depth==numbers.length){depth=depth-1;if(!charge(list))//printList(ArrayToList(list));resultlist.add(ArrayToList(list));return;}for (int i = 0; i < numbers.length; i++) {// System.out.println("depth="+depth);list[depth++]=numbers[i];dfs(numbers,list);}depth--;return;}private static boolean charge(int nums[]){for (int i = 0; i < nums.length; i++) {for (int j = i+1; j < nums.length; j++) {if(nums[i]==nums[j]){return true;}}}return false;}private static int getcount(List list){/*** 计算合法排列个数* */int count=0;for (int i = 0; i < list.size(); i++) {for (int j = i+1; j < list.size(); j++) {int temp1=(Integer) list.get(i);int temp2=(Integer) list.get(j);if(i<j&&temp1<temp2){count++;}}}return count;}private static List<Integer> getnums(int nums []){/** 把含零数组中非零元素提取出来转换为list* **/List<Integer> list = new LinkedList<Integer>();for (int i = 0; i < nums.length; i++) {if(nums[i]!=0)list.add(nums[i]);}return list;}private static List<Integer> get_no_nums(int nums []){/** 把含零数组中非零元素提取出来转换为list* **/List<Integer> list1=ArrayToList(nums);List<Integer> list = new LinkedList<Integer>();for (int i = 1; i <= nums.length; i++) {if(list1.contains(i))continue;else list.add(i);}return list;}}
import java.util.Scanner;
import java.util.ArrayList;
//从数列的第一位开始递归,遇到0要尝试所有可能的数(回溯)
//遇到非0则只计算当前位置之前的顺序对数,然后继续下一位
//注意:每次回溯要更新list和count
public class Main{
private static ArrayList<Integer> list = new ArrayList<>();
private static int count = 0; //顺序对对数
private static int num = 0; //符合条件的排列数目
public static void main(String[] args){
Scanner in = new Scanner(System.in);
while(in.hasNextInt()){
int n = in.nextInt();
int k = in.nextInt();
ArrayList<Integer> tempList = new ArrayList<>();
int[] arr = new int[n];
for(int i = 0; i < n; i++){
arr[i] = in.nextInt();
tempList.add(arr[i]);
}
for(int i = 1; i <= n; i++){
if(!tempList.contains(i)){
list.add(i);
}
}
permutation(arr, 0, k);
System.out.println(num);
}
}
private static void permutation(int[] arr, int index, int k){
if(index >= arr.length){
return;
}
if(arr[index] == 0){
for(int i = 0; i < list.size(); i++){
arr[index] = list.remove(i);
int pairs = calc(arr, index);
count += pairs;
if(index == arr.length-1 && count == k){
num++;
}
permutation(arr, index+1, k);
count -= pairs;
list.add(i, arr[index]);
arr[index] = 0;
}
}else{
int pairs = calc(arr, index);
count += pairs;
if(index == arr.length-1 && count == k){
num++;
}
permutation(arr, index+1, k);
count -= pairs;
}
}
private static int calc(int[] arr, int index){
int cnt = 0;
for(int i = 0; i < index; i++){
if(arr[i] < arr[index])
cnt++;
}
return cnt;
}
} import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Collections;
public class Main {
/**
*如果给我们一个序列(不含有任何未知的元素),我们可以通过两次循环获取有多少个顺序对。
*但是如果插入一个未知元素,顺序对变化了多少呢?等于这个元素与前面元素的新增的顺序对,和后面比较的新增的顺序对。
*如果插入多个呢?可以逐次插入,让每次只有一个位置插入元素,其他未知临时忽略就可以了。这样就能递归解决问题。
*一个序列的总的顺序对,等于插入前的对数,加上逐次插入未知产生的对数。
*总的合法排列就等于未知数排列的合法排列数。
*/
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] arrInput = br.readLine().trim().split(" ");
int n = Integer.parseInt(arrInput[0]);
int k = Integer.parseInt(arrInput[1]);
int[] arrNum = new int[n];
int knownedSeqPair = 0;
ArrayList<Integer> listIndex = new ArrayList<Integer>();//记住模糊位置的索引
ArrayList<Integer> listBlur = new ArrayList<Integer>();//记住模糊数字
HashSet<Integer> setBook = new HashSet<Integer>();//找到模糊数字的工具
arrInput = br.readLine().trim().split(" ");
for (int i=0; i<arrInput.length; i++) {
arrNum[i] = Integer.parseInt(arrInput[i]);
if (arrNum[i] == 0) {//模糊的记住位置,用于擦除数据
listIndex.add(i);
} else {//不模糊的记住数据本身,用于找到模糊的数据
setBook.add(arrNum[i]);
}
}
for (int i=1; i<=n; i++) {//查找模糊的数字
if (false == setBook.contains(i)) {
listBlur.add(i);
}
}
for (int i=0; i<arrNum.length; i++) {
if (arrNum[i] != 0) {//不能是模糊数字
for (int j=i+1; j<arrNum.length; j++) {
if (arrNum[j] != 0 && arrNum[i] < arrNum[j]) {//不能是模糊数字
knownedSeqPair++;
}
}
}
}
System.out.println(Main.getSeqNum(arrNum, listBlur, listIndex, knownedSeqPair, 0, k));
}
public static int getSeqNum(int[] arrNum, ArrayList<Integer> listBlur, ArrayList<Integer> listIndex, int knownedSeqPair, int n, int k) {
int result = 0;
if (n == listBlur.size()) {//子排列已经出现
int sumSeqNum = knownedSeqPair;
int i = 0;
int j = 0;
for (i=0; i<listBlur.size(); i++) {//计算新增的排列
for (j=0; j<arrNum.length && arrNum[j] != 0; j++) {//前半部分
if (arrNum[j] < listBlur.get(i)) {
sumSeqNum++;
}
}
if (j < arrNum.length) {//插入,为下次会比较,判断是为了应对根本没有未知的情况
arrNum[j++] = listBlur.get(i);
}
for (; j<arrNum.length; j++) {//比较后面
if (arrNum[j] != 0 && arrNum[j] > listBlur.get(i)) {
sumSeqNum++;
}
}
}
for (i=0; i<listIndex.size(); i++) {//擦除模糊数字的排列,用于下次
arrNum[listIndex.get(i)] = 0;
}
if (sumSeqNum == k) {
result = 1;
}
} else {
for (int i=n; i<listBlur.size(); i++) {//其实等于n是因为不交换(自交换)也是一种情况。
Collections.swap(listBlur, n, i);
result += Main.getSeqNum(arrNum, listBlur, listIndex, knownedSeqPair, n+1, k);
Collections.swap(listBlur, n, i);
}
}
return result;
}
}
//方法是牛客网---hofighter提供的,个人只是加了一些注释,方便自己和大家理解
/**思路:首先将模糊的数字统计出来,并求出这些数字的全排列,然后对每个排列求顺序对
关键去求全排列,需要递归的求出所有排列。。。
ps:第一次做的时候没看清楚题,以为可以有重复数字,直接深搜计算了,结果。。。*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
public class Main{
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
int RES = 0;
int n = sc.nextInt();
int k = sc.nextInt();
int[] A = new int[n];
boolean[] flag = new boolean[n+1];//为什么是 n+1?因为n是从1开始的,必须有flag[n]
//flag标记哪些数字已经存在
for(int i=0;i<n;i++){
A[i] = sc.nextInt();
if(A[i] != 0){
flag[A[i]] = true;
}
}
//统计排列中不存在的数字
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i=1;i<=n;i++){
if(flag[i] == false)
list.add(i);
}
//perm用来存模糊数字的全排列
List<ArrayList<Integer>> perm = new ArrayList<ArrayList<Integer>>();
//计算perm
calperm(perm, list, 0);
//统计已有的排列的顺序对
int cv = 0;
for(int i=0;i<n;i++){
if(A[i]!= 0){
for(int j=i+1;j<n;j++){
if(A[j] != 0 && A[i] < A[j])
cv++;
}
}
}
//计算每个模糊数字排列的顺序对,如果与k相等,则结果RES加一
for(ArrayList<Integer> tmp : perm){
int val = cv;
int[] tmpA = Arrays.copyOf(A, n);
val += calvalue(tmp, tmpA);
if(val == k)
RES++;
}
System.out.println(RES);
}
}
/**
* 计算排列的顺序对
* @param list 模糊数列的某个排列
* @param A 最终的某个排列
*/
public static int calvalue(List<Integer> list, int[] A){
int val = 0;
int j = 0;
for(int i=0;i<A.length;i++){
if(A[i] == 0){
A[i] = list.get(j++);//每一一个为0的位置 安插一个list中的数字
for(int k = 0;k<i;k++){
if(A[k]!=0 && A[k]<A[i])
val++;
}
for(int k=i+1;k<A.length;k++){
if(A[k]!=0 && A[k]>A[i])
val++;
}
}
}
return val;//最后返回时因为必须报list中的所有数据安插在为0的位置上
}
/**
* 计算全排列
* @param perm
* @param list 排列中不存在的数字
* @param n 初始为0
*/
public static void calperm(List<ArrayList<Integer>> perm , ArrayList<Integer> list, int n){
if(n == list.size()){
perm.add(new ArrayList<Integer>(list));
}else{
for(int i=n;i<list.size();i++){
Collections.swap(list, i, n);
calperm(perm, list, n+1);
Collections.swap(list, i, n);
}
}
}
}
#include <bits/stdc++.h>
using namespace std;
int getorderpair(int arr[],int n,int num,int pos){
int sum=0;
for(int i=0;i<n;++i){
if (!arr[i]) continue;
sum+=((arr[i]<num && i<pos)||(arr[i]>num && i>pos));
}
return sum;
}
int getorderpairall(int arr[],int n){
int sum=0;
for(int i=0;i<n;++i){
if (!arr[i]) continue;
sum+=getorderpair(arr,n,arr[i],i);
}
return sum/2; // each pair cal twice.
}
int main(){
int arr[100],can[10]; // missing num
unordered_set<int> s;
for(int n,k,c,base,ans;cin>>n>>k;c=0,s.clear()){
for(int i=ans=0;i<n;++i){
cin>>arr[i];
s.insert(arr[i]);
}
for(int i=c=0;i<n;++i){ // find missing num
if (s.find(i+1)==s.end()) can[c++]=i+1;
}
int arrbase = getorderpairall(arr,n);
do{
int canbase = getorderpairall(can,c);
for(int i=base=0,j=0;i<n;++i){
if (arr[i]) continue;
base+=getorderpair(arr,n,can[j++],i);
}
if (arrbase+canbase+base==k) ++ans;
}while(next_permutation(can,can+c));
cout<<ans<<endl;
}
return 0;
}