数字全排列

数字全排列

 

Time Limit:   1000MS       Memory Limit:   65535KB
Submissions:   57       Accepted:   33

 

Description
从1~9之间顺序取N个数字,组成每位数不重复的所有可能的N位数,按从小到大的顺序进行编号,当输入其中的任何一个数M是,能找出该数对应的编号。如:当N = 3,M = 132时,则输出: [123(1), 132(2), 213(3), 231(4), 312(5), 321(6)]——> X = 2
Input
输入只有一行,两个正整数N和M(1 ≤ N ≤ 9,1 ≤ K ≤ 987654321),之间用一个空格分隔开。
Output
输出对应的编号X。

Sample Input

3 132

Sample Output

2

解法一:
# include<stdio.h>
int solve(int num)
{
    int sign=1,i;
    for(i=1;i<=num;i++)
        sign*=i;
    return sign;
}
int main()
{
    char str[20];
    int n,sum=0,count=0,i,j;
    scanf("%d %s",&n,str);
    for(i=0;i<n-1;i++)
    {
        count=0;
        for(j=i+1;j<n;j++)
            if(str[j]<str[i])count++;//计算逆序数
        sum+=count*solve(n-i-1);//后面可能出现的情况计算
    }
    printf("%d\n",sum+1);
    return 0;
    
}

解法二:

#include<stdio.h>//深度搜索
# include<string.h>
int n,loop,vis[100],j,result[100],Count,sign;
char str[100];
void DFS(int step)
{
    int i;
    sign=0;
    if(step==n+1)
    {
        Count+=1;
        for(i=1;i<=n;i++)
        {
            if(result[i]==str[i-1]-'0')
                sign+=1;
        }
        if(sign==n)
        loop=Count;
        return;
    }
    for(i=1;i<=n;i++)
    {
        if(!vis[i])
        {
            vis[i]=1;
            result[step]=i;
            DFS(step+1);
            vis[i]=0;
        }
    }
}
int main()
{
    scanf("%d %s",&n,str);
    memset(vis,0,sizeof(vis));
    Count=0;
    sign=0;
    DFS(1);
    printf("%d\n",loop);
    return 0;
}

 解法三:

//第一种方法在algorithm里面有个next_permutation可以实现,排序道理是一样的
//如果把next_permutation换成prev_permutation,一开始赋值就应是倒序,如:321
# include<iostream>
# include<cstring>
# include<algorithm>
using namespace std;
int main()
{
    int num,count=0,i;
    char str[20],s[20];
    cin>>num>>str;
    for(i=0;i<num;i++)
        s[i]=i+1+'0';
    s[i]='\0';
    do
    {
        count++;
        if(strcmp(str,s)==0)
        {
            cout<<count<<endl;
            break;
        }
    }
    while(next_permutation(s,s+num));
    return 0;
}

 解法四:

//望高手改改,使之按字典顺序来排

//换位的递归思想还不错,就是没按字典顺序来,仅供看思想
# include<iostream>
using namespace std;
char str[20];
int t,leap;
void Swap(int *a,int *b)//重视
{
  int temp;
   temp=*a;
    *a=*b;
    *b=temp;
}
void Array(int *s,int Count,int n)
{
    if(leap)return;
    if(Count==n)
    {
        t++;
        int sign=0;
        for(int i=0;i<=n;i++)
        if(s[i]==str[i]-'0')sign++;
        if(sign==n+1)
        {
            cout<<t<<endl;
            leap=1;
        }
        return;
    }
    for(int i=Count;i<=n;i++)
    {
    
        Swap(&s[i],&s[Count]);
        Array(s,Count+1,n);
        Swap(&s[i],&s[Count]); 
    }

}
int main()
{
    int s[20];
    int num,i;
    while(cin>>num>>str)
    {
    t=0;
    leap=0;
    for(i=0;i<num;i++)
        s[i]=i+1;
    Array(s,0,num-1);
    }
    return 0;
}

 

posted on 2012-05-20 19:40  即为将军  阅读(496)  评论(0)    收藏  举报

导航