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.