您的位置:首页 > 其它

湖南多校对抗赛(2015.4.6)C

2017-07-29 21:27 375 查看



1563: Lexicography

Submit Page    

Summary    Time
Limit: 1 Sec     Memory
Limit: 128 Mb     Submitted: 444     Solved: 142    


Description

An anagram of a string is any string that can be formed using the same letters as the original. (We consider the original string an anagram of itself as well.) For example, the string ACM has the following 6 anagrams, as given in alphabetical order:

ACM

AMC

CAM

CMA

MAC

MCA

As another example, the string ICPC has the following 12 anagrams (in alphabetical order):

CCIP

CCPI

CICP

CIPC

CPCI

CPIC

ICCP

ICPC

IPCC

PCCI

PCIC

PICC

Given a string and a rank K, you are to determine the Kth such anagram according to alphabetical order.


Input

Each test case will be designated on a single line containing the original word followed by the desired rank K. Words will use uppercase letters (i.e., A through Z) and will have length at most 16. The value of K will be in the range from 1 to the
number of distinct anagrams of the given word. A line of the form "# 0" designates the end of the input.


Output

For each test, display the Kth anagram of the original string.


Sample Input

ACM 5
ICPC 12
REGION 274
# 0



Sample Output

MAC
PICC
IGNORE

思路:一开始没想到有重复的字母,所以直接算阶乘了,结果第二组测试样据过不了,于是就重新找规律,它的序列数应该是len的阶乘除以重复字母的阶乘,然后就可以从头往后找,如果这个位置的序列数恰好大于n,说明该位置是是这个字母,然后继续往后找,知道全部找齐。

代码:

#include <set>
#include <map>
#include <cmath>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define ma(a) memset(a,0,sizeof(a))
#define ll long long
ll a[50];
void get()
{
int i;
a[0]=1;
for(i=1;i<=16;i++)
a[i]=a[i-1]*i;
}
int main()
{
char c[50];
get();
while(cin>>c)
{
ll n;
int i,j,k;
scanf("%lld",&n);
if(c[0]=='#'&&n==0)
break;
int len=strlen(c);
sort(c,c+len);
int flag[50];
ma(flag);
for(i=0;i<len;i++)
{
flag[c[i]-'A']++;
}
char ma[50];
for(i=0;i<len;i++)
{
ll x=0,y=0;
for(j=0;j<26;j++)
{
if(flag[j])//这表示该字母还未找到位置
{
x=a[len-1-i];
for(k=0;k<26;k++)
{
if(k==j)x/=a[flag[k]-1];
else x/=a[flag[k]];
}//len的阶乘除去重复字母的阶乘才是真正的序列数
if(x+y>=n)
{
ma[i]=j+'A';
n-=y;
flag[j]--;//找到过的字母减去一个;

c08a
break;
}
else y+=x;
}
}
}
for(i=0;i<len;i++)
{
cout<<ma[i];
}
cout<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: