字典序问题
时间: 1ms 内存:64M
描述:
在数据加密和数据压缩中常需要对特殊的字符串进行编码。给定的字母表A由 26 个小写英文字母组成A={a,b,…,z}。该字母表产生的升序字符串是指字符串中字母按照从左到右出现的次序与字母在字母表中出现的次序相同,且每个字符最多出现1次。例如,a,b,ab,bc,xyz等字符串都是升序字符串。现在对字母表A 产生的所有长度不超过6 的升序字符串按照字典序排列并编码如下。
对于任意长度不超过6 的升序字符串,迅速计算出它在上述字典中的编码。对于给定的长度不超过6 的升序字符串,计算出它在上述字典中的编码。
输入:
输入数据的第一行是一个正整数k,表示接下来共有k行。接下来的k行中,每行给出一个字符串。
输出:
将计算结果输出,共有k行,每行对应于一个字符串的编码,对于非法字符串序列输出0。
示例输入:
2
a
b
示例输出:
1
2
提示:
参考答案(内存最优[1096]):
#include<stdio.h>
#include<string.h>
unsigned long alc(int m,int n)
{
unsigned long c=1;
int i,j;
for(i=m,j=1; j<=n; j++,i--)
c=c*i/j;
return c;
}
int panduan(char *c)
{
if(!(c[0]<='z'&&c[0]>='a')||strlen(c)>6)return 0;
for(int i=1; c[i]!='\0'; i++)
if(c[i]<=c[i-1]||!(c[i]<='z'&&c[i]>='a'))return 0;
return 1;
}
int main()
{
int i,k,len,n,w=26;
char str[30],ch;
unsigned long a1,a2;
scanf("%d",&n);
for(k=0; k<n; k++)
{
a1=0,a2=0;
scanf("%s",str);
len=strlen(str);
if(panduan(str))
{
ch='a';
for(i=0; i<len-1; i++)
{
a1+=alc(w,i+1);
while(str[i]>ch)
{
a2+=alc((w-1-(ch-'a')),len-1-i);
ch++;
}
ch++;
}
a2+=str[i]-ch+1;
}
printf("%ld\n",a1+a2);
}
return 0;
}
参考答案(时间最优[0]):
#include<stdio.h>
#include<string.h>
unsigned long alc(int m,int n)
{
unsigned long c=1;
int i,j;
for(i=m,j=1; j<=n; j++,i--)
c=c*i/j;
return c;
}
int panduan(char *c)
{
if(!(c[0]<='z'&&c[0]>='a')||strlen(c)>6)return 0;
for(int i=1; c[i]!='\0'; i++)
if(c[i]<=c[i-1]||!(c[i]<='z'&&c[i]>='a'))return 0;
return 1;
}
int main()
{
int i,k,len,n,w=26;
char str[30],ch;
unsigned long a1,a2;
scanf("%d",&n);
for(k=0; k<n; k++)
{
a1=0,a2=0;
scanf("%s",str);
len=strlen(str);
if(panduan(str))
{
ch='a';
for(i=0; i<len-1; i++)
{
a1+=alc(w,i+1);
while(str[i]>ch)
{
a2+=alc((w-1-(ch-'a')),len-1-i);
ch++;
}
ch++;
}
a2+=str[i]-ch+1;
}
printf("%ld\n",a1+a2);
}
return 0;
}
题目和答案均来自于互联网,仅供参考,如有问题请联系管理员修改或删除。