题目如下:
The Mad Numerologist
Numerology is a science that is used by many people to findout a mans personality, sole purpose of life, desires to experience etc. Somecalculations of numerology are very complex, while others are quite simple. Youcan sit alone at home and do these easy calculations without taking any oneshelp. However in this problem you wont be asked to find the value of yourname.
- The name has a predefined length N.
- The vowel value and consonant value of the name must bekept minimum.
- To make the pronunciation of the name possible vowelsand consonants are placed in alternate positions. Actually vowels are put inodd positions and consonants are put in even positions. The leftmost letter ofa name has position 1; the position right to it is position 2 and so on.
- No consonants can be used in a name more than fivetimes and no vowels can be used in a name more than twenty-one times
- Following the rules and limitations above the name mustbe kept lexicographically smallest. Please note that the numerologists firstpriority is to keep the vowel and consonant value minimum and then to make thename lexicographically smallest.
Input
First line of the input file contains an integer N ( 0 <N250) that indicates howmany sets of inputs are there. Each of the next N lines contains a single setof input. The description of each set is given below:Each line contains an integer n ( 0 < n < 211) that indicates the predefined length of the name.
Output
For each set of input produce one line of output. This linecontains the serial of output followed by the name that the numerologist wouldsuggest following the rules above. All letters in the output should beuppercase English letters.Sample Input
3 1 5 5
Sample Output
Case 1: A Case 2: AJAJA Case 3: AJAJA
本题看似高端,其实是道比较水的题,要求名字中的元音字母对应的数字之和最小和辅音字母对应的数字之和最小,并且在此条件下,该名字还应是字典序最小。思路是把元音字母和辅音字母与数字的对应用两个数组实现(只需要实现顺序即可并不需要知道具体对应的数字,因为只需要输出满足和最小的名字而不需要输出和),因为每个元音字母最多出现21次,而辅音最多出现5次,所以应对应时设置21个相同字母和5个相同字母,对名字数组中的每个位置,若是奇数,遍历元音数组,反之遍历辅音数组。这样就能满足和最小。再对得到的名字分别对元音和辅音排序,使之满足字典序最小。刚开始误认为只要遍历了数组,就一定是字典序最小,WA了,后来发现交换字母的顺序和不变但可以使字典序更小。
AC的代码如下:
#include
#include
#include
int cmp(const void *a,const void *b)
{
return *(char *)a-*(char *)b;
}
int main()
{
char result1[120],result2[120];
int n,p=0,q=0;
scanf("%d",&n);
int i,Case[250];
for(i=0; i<=n-1; i++)
{
scanf("%d",&Case[i]);
int j;
char vowels[]="AAAAAAAAAAAAAAAAAAAAAUUUUUUUUUUUUUUUUUUUUUEEEEEEEEEEEEEEEEEEEEEOOOOOOOOOOOOOOOOOOOOOIIIIIIIIIIIIIIIIIIIII";
char consonant[]="JJJJJSSSSSBBBBBKKKKKTTTTTCCCCCLLLLLDDDDDMMMMMVVVVVNNNNNWWWWWFFFFFXXXXXGGGGGPPPPPYYYYYHHHHHQQQQQZZZZZRRRRR";
int len1=strlen(vowels),len2=strlen(consonant);
for(j=0; j<=Case[i]-1; j++)
{
if((j+1)%2!=0)
{
int k;
for(k=0; k<=len1-1; k++)
if(vowels[k]!='#')
{
result1[p++]=vowels[k];
vowels[k]='#';
break;
}
}
else
{
int k;
for(k=0; k<=len2-1; k++)
if(consonant[k]!='#')
{
result2[q++]=consonant[k];
consonant[k]='#';
break;
}
}
}
result1[p]='\0';
result2[q]='\0';
qsort(result1,p,sizeof(char),cmp);
qsort(result2,q,sizeof(char),cmp);
printf("Case %d: ",i+1);
p=0;
q=0;
for(j=0; j<=Case[i]-1; j++)
{
if((j+1)%2!=0)
printf("%c",result1[p++]);
else
printf("%c",result2[q++]);
}
printf("\n");
memset(result1,'\0',sizeof(result1));
memset(result2,'\0',sizeof(result2));
p=0;
q=0;
}
return 0;
}