• 全排列散列


    题目描述

           Did you remember that simple problem permutation of five? Now, TY has meeted another problem about permutation. Help him.
           You are given two numbers, n and m. The permutation is based on n digits. 
           First, you should point out the m th permutation of all permutations in an ascend order. Than reverse that permutation and print the rank of that reversed permutation of all permutations in an ascend order.

    输入

    Multiple cases( > 1000). Each case contains a line with two integer, n,m. (1 <= n <= 9, 1 <= m <= n!)

    输出

    Each case a line, the mth permutation and the rank, seperated by a space.

    样例输入

    5 1
    5 10
    

    样例输出

    12345 120
    13452 48
    
    
    
    #include<iostream>
    using namespace std;
    int n, m;
    bool used[10];
    int a[9];
    int fac[10];
    void  factorial(){
    	int i;
    	fac[0] = 1;
    	for (i = 1; i < 10; i++)
    		fac[i] = i*fac[i - 1];
    }
    int getNum(int i){
    	int j,k=0;
    	for (j = 1; k<i;j++)
    	if (used[j] == false)k++;
    	return j-1;
    }
    void find(){
    	int i;
    	for (i = 0; i < n; i++){
    		a[i]=getNum( m / fac[n - 1-i]+1);
    		used[a[i]] = true;
    		m %= fac[n-i - 1];
    	}
    }
    void turn(){
    	int i, j;
    	for (i = 0; i * 2 < n; i++){
    		j = a[i];
    		a[i] = a[n - i-1];
    		a[n - i-1] = j;
    	}
    }
    int which(int n){
    	int i, j=0;
    	for (i = 0; i < n; i++)
    	{
    		if (used[i] == false)j++;
    	}
    	return j;
    }
    int toNum(){
    	int i, k = 0;
    	for (i = 0; i < n; i++){
    		k += fac[n-i-1] * (which(a[i])-1);
    		used[a[i]] = true;
    	}
    	return k;
    }
    int main(){
    	//freopen("in.txt", "r", stdin);
    	factorial();
    	while (scanf("%d%d",&n,&m)!=-1){
    		memset(used, 0, sizeof(used));
    		m--;
    		find();
    		int i;
    		for (i = 0; i < n; i++)
    			 printf("%d",a[i]);
    		cout << " ";
    		turn();
    		memset(used, 0, sizeof(used));
    		printf("%d
    ", toNum() + 1);
    	}
    	return 0;
    }


  • 相关阅读:
    Android 通过ViewFlipper实现广告轮播功能并可以通过手势滑动进行广告切换
    [C#][DevPress]自定义数据分页控件
    [C#][SQLLITE]一个数据分页技巧
    [C#]用SharpZipLib压缩多个文件
    [C#][DevPress]省市县乡嵌套查询
    [C#][DevPress]事件委托的使用
    [C#]Excel操作类
    [C#][DevPress]手动添加控件中的子控件或者结构
    [C#]XML操作类
    [C#]把DataTable转换成泛型实体List
  • 原文地址:https://www.cnblogs.com/weiyinfu/p/5013904.html
Copyright © 2020-2023  润新知