http://acm.pku.edu.cn/JudgeOnline/problem?id=1196
Секретные сообщения между Санта-Клаусом и его маленькими помощниками обычно кодируются так называемым 25-языком. В этом языке используется 25-алфавит, который совпадает с латинским алфавитом с одним исключением – в нем отсутствует буква 'Z', то есть 25-алфавит содержит 25 латинских букв от 'A' до 'Y' в том же порядке, что и латинский алфавит. Каждое слово в 25-языке состоит ровно из 25 различных букв. Слово записывается в таблице размера 5x5, строка за строкой. Например, слово ADJPTBEKQUCGLRVFINSWHMOXY будет записано так:
A D J P T
B E K Q U
C G L R V
F I N S W
H M O X Y
Правильным словом 25-языка считается слово, буквы которого в каждой строке и каждом столбце расположены по возрастанию их номера в алфавите. Поэтому слово ADJPTBEKQUCGLRVFINSWHMOXY является правильным словом, а слово ADJPTBEGQUCKLRVFINSWHMOXY - нет (возрастающий порядок нарушается во втором и третьем столбцах).
Лексикон Санта-Клауса состоит из всех правильных слов 25-языка. Слова расположены в возрастающем лексикографическом порядке и пронумерованы, начиная с единицы. Например, в лексиконе Санта-Клауса слово ABCDEFGHIJKLMNOPQRSTUVWXY имеет номер 1, а слово ABCDEFGHIJKLMNOPQRSUTVWXY имеет номер 2. Во втором слове, по сравнению с первым, буквы U и Т поменялись местами.
К сожалению, лексикон Санта-Клауса огромен. Напишите программу, которая определяет порядковый номер по заданному слову из лексикона Санта-Клауса, а по заданному порядковому номеру определяет соответствующее слово. В лексиконе Санта-Клауса не больше 231 слов.
ВВОД
Входной файл имеет имя twofive.in и состоит из двух строк. Первая строка содержит один из символов 'W' или 'N'. Если первая строка содержит 'W', тогда вторая строка содержит правильное слово 25-языка, то есть строку из 25 символов. Если первая строка содержит 'N', то вторая строка содержит порядковый номер существующего слова 25-языка.
ВЫВОД
Выходной файл имеет имя twofive.out. Если вторая строка входного файла содержит слово 25-языка, то единственная строка выходного файла должна содержать его порядковый номер в лексиконе Санта-Клауса. Если вторая строка входного файла содержит число, то единственная строка выходного файла должна содержать слово 25-языка с этим номером.
ПРИМЕРЫ ВВОДА И ВЫВОДА
twofive.in
W
ABCDEFGHIJKLMNOPQRSUTVWXY
twofive.out
2
twofive.in
N
2
twofive.out
ABCDEFGHIJKLMNOPQRSUTVWXY
const states=6*6*6*6*6; var num:longint; c:char; str:string; lx,ly:array[ 1..25 ] of integer; state:array[ 0..5 ] of longint; f:array[ 0..states-1 ] of longint; function calc(l:integer):longint; var i,a,b,c:longint; begin a:=state[ 1 ]; for i:=2 to 5 do a:=a*6+state[ i ]; if f[ a ]<0 then begin b:=0;c:=lx[ l ]; if c<0 then begin for i:=1 to 5 do if state[ i ]<state[ i-1 ] then begin inc(state[ i ]); inc(b,calc(l+1)); dec(state[ i ]); end end else if (state[ c-1 ]>state[ c ]) and (state[ c ]+1=ly[ l ]) then begin inc(state[ c ]); inc(b,calc(l+1)); dec(state[ c ]); end; f[ a ]:=b; end; calc:=f[ a ]; end; function numconts:longint; begin fillchar(f,sizeof(f),$ff); fillchar(state,sizeof(state),0); state[ 0 ]:=5; f[ states-1 ]:=1; numconts:=calc(1); end; function wordtonum:longint; var i,j,k,ch:integer; begin fillchar(lx,sizeof(lx),$ff); num:=1; for i:=1 to 5 do for j:=1 to 5 do begin ch:=ord(str[ (i-1)*5+j ])-64; for k:=1 to ch-1 do if lx[ k ]<0 then begin lx[ k ]:=i; ly[ k ]:=j; inc(num,numconts); lx[ k ]:=-1; end; lx[ ch ]:=i; ly[ ch ]:=j; end; wordtonum:=num; end; procedure numtoword; var i,j,k:integer; out:array[ 1..25 ] of char; l:longint; begin fillchar(lx,sizeof(lx),$ff); for i:=1 to 5 do for j:=1 to 5 do for k:=1 to 25 do if lx[ k ]<0 then begin lx[ k ]:=i; ly[ k ]:=j; l:=numconts; if num>l then dec(num,l) else break; lx[ k ]:=-1; end; for i:=1 to 25 do out[ (lx[ i ]-1)*5+ly[ i ] ]:=chr(64+i); for i:=1 to 25 do write(out[ i ]); writeln; end; begin //assign(input,'twofive.in'); //assign(output,'twofive.out'); //reset(input); //rewrite(output); readln(c); if c='W' then begin readln(str); writeln(wordtonum); end else begin readln(num); numtoword; end; //close(input); //close(output); end.