康拓函数 HDU1027的解决之路

https://blog.csdn.net/lttree/article/details/24798653

网上有答案是用了STL做的,这个是用 的康拓函数,用的是数学知识。

很经典的就是逆康拓函数里面根据某一位数的数怎样由 bi小的比它的个数 来推算出来(用了一个vst数组)。

#include <iostream>
using namespace std;

const int maxn=1001;
int  fac[] = {1,1,2,6,24,120,720,5040,40320}; 

int kangtuo(int n,char a[])
{
    int i,j,t;
    int sum=0;
    for(int i=0;i<n;i++)
    {
        t=0;
        for(j=i+1;j<n;j++)
        {
            if(a[i]>a[j])
                t++;
        }
        sum+=t*fac[n-i-1];
    }
    return sum+1;


int main()
{
    int n;
    char a[1001];
    cin >> n;
    cin >> a;
    cout << kangtuo(n,a) << endl;
    return 0;
}

//实现康拓函数的逆运算  HDU 1027(N小的时候可以解决)
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int  fac[] = {1,1,2,6,24,120,720,5040,40320}; 
int N,M;
const int maxn=1001;
char a[maxn];

void reverse_kangtuo(int N,int M)//M是M位,N是到N 
{
    M--;
    memset(a,'\0',sizeof(a));
    int i,j,t,k=M,vst[9]={0};
    
    for(i=0;i<N;i++)
    {
        t=k/fac[N-i-1];
        for(j=1;j<=N;j++)
        {
            if(!vst[j])
            {
                if(t==0)
                    break;
                t--;    
            }            
        }
        vst[j]=1;
        a[i]='0'+j;
        k=k%fac[N-i-1];
    }
    for(i=0;a[i]!='\0';i++)
        cout << a[i]-'0' << ' ';
    cout << endl;
}

int main()
{
    while(~scanf("%d%d",&N,&M)!=EOF)
    {
        reverse_kangtuo(N,M);
    }
    
    return 0;
}

//利用next_permutation

#include <iostream>
#include <algorithm>
using namespace std;
 
int main(){
    int n, m, p[1005];
    while(cin >> n >> m){
        for(int i = 0; i < n; i++)
            p[i] = i + 1;
        while(--m)
            next_permutation(p, p + n);
        for(int j = 0; j < n; j++)
            j == n - 1 ? printf("%d\n", p[j]) : printf("%d ", p[j]);     //这个三目运算符用的很好

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41755258/article/details/81509582