JSOI2008 编码
解题报告 JSOI2008 编码
【题目描述】
编码工作常被运用于密文或压缩传输。这里我们用一种最简单的编码方式进行编码:把一些有规律的单词编成数字。字母表中共有26个字母{a,b,……,z},这些特殊的单词长度不超过6且字母按升序排列。把所有这样的单词放在一起,按字典顺序排列,一个单词的编码就对应着它在字典中的位置。例如:a --> 1b --> 2z --> 26ab --> 27ac --> 28你的任务就是对于所给的单词,求出它的编码。
【输入文件】
一行,指被编码的单词。
【输出文件】
一个数,指输入单词的编码。
【输入样例】
ab
【输出样例】
27
【题目分析】
这个题在省选题目中算是比较水的了。
一开始以为字母可以重复,后来发现不能重复,并且字母都是单调的。
那么,长度为i的单词个数为C(26,i)
设给定单词的长度为l
那么首先让ans=sigma(C(26,i),1<=i<=l-1);
然后,对于长度为l的,直接搜索就可以了,最大的单词uvwxyz才30多万而已,搜索时按字典序优先,每搜到长度为l就给ans加1,搜到给出的单词就可以输出结果了。
【代码实现】
Code
1 program tyvj1811;
2 var st:ansistring;
3 ans:longint;
4 b:boolean;
5 l:longint;
6 i,j:longint;
7 function c(x,y:longint):longint;
8 var t,i:longint;
9 begin
10 t:=1;
11 for i:=1 to y do t:=t*(x-i+1);
12 for i:=1 to y do t:=t div i;
13 exit(t);
14 end;
15 procedure dfs(i:longint;s:ansistring);
16 var c,ch:char;
17 begin
18 if i=l then
19 begin
20 inc(ans);
21 if s=st then b:=true;
22 exit;
23 end;
24 if i=0 then ch:='a'
25 else ch:=succ(s[i]);
26 for c:=ch to 'z' do
27 begin
28 dfs(i+1,s+c);
29 if b then exit;
30 end;
31 end;
32 begin
33 readln(st);
34 l:=length(st);
35 for i:=1 to l do
36 if not(st[i] in ['a'..'z']) then
37 begin
38 writeln(0);
39 halt;
40 end;
41 for i:=1 to l-1 do
42 for j:=i+1 to l do
43 if st[i]=st[j] then
44 begin
45 writeln(0);
46 halt;
47 end;
48 for i:=1 to l-1 do ans:=ans+c(26,i);
49 dfs(0,'');
50 writeln(ans);
51 end.