Гыхм... Я уже ухожу сегодня, появлюсь теперь не знаю когда. Так что выкладываю свое решение. В процессе решения мне на ум приходили оба предложенных решения (и еще парочка), но первое я сразу отмел из-за наличия перебора, второе - не сумел довести до ума, не хватило терпения (или соображалки).
Может мои рассуждения вам покажутся чересчур сложными, но решал задачу я именно так (на подобные выкладки меня натолкнули воспоминания о прочитанном от корки до корки "Искусстве программирования" Кнута).
Итак. Для начала строим дерево следующего вида: корень (уровень №0) - некий пустой элемент, из него выходят девять ветвей к узлам 1, 2, ..., 8, 9 - уровень №1; из каждого эелемента 1-го уровня также выходят ветви т.о., чтобы путь к ним по узлам (цифрам в узлах) не содержал повторяющихся цифирей, например, из узла (1) 1-го уровня выходят ветви к узлам 0, 2, 3, ..., 8, 9. И т.д. - всего 10 уровней, что очевидно - не может существовать десятичное число с неповторяющимися цифрами длиной более 10. Т.о., при проходе сверху-вниз по этому дереву всегда получается "разноциферное" число.
Само это дерево в программе не потребуется, и строить его не нужно будет. Важны некоторые характеристики уровней. А именно:
- T - количество ветвей, спускающихся в текущий уровень из любого элемента предыдущего уровня. Т.е., фактически, какое количество цифр можно добавить к уже существующему "разноциферному" числу, не нарушая его. Это число легко определяется следующим образом:
T[1] = 9;
T[i] = 11 - i, 1<i<=10.
- F - общее число узлов в уровне, т.е., в приложении к данной задаче, - количество 1-, 2-, 3-значных "разноциферных" чисел и т.д. Это число тоже легко вычисляется:
F[1] = T[1];
F[i] = T[i] x F[i - 1], 1<i<=10.
- S - общее число узлов в дереве по текущий уровень включительно или, другими словами, количество "разноциферных" чисел длины не более 2, 3, и т.д.:
S[1] = F[1];
S[i] = F[i] + S[i - 1], 1<i<=10.
Все эти числа легко найти и занести в массивы. Можно, конечно, составить специальные функции для вычисления каждого числа, но проще посчитать один раз и потом результаты хранить и использовать - благо дело места требуется немного. Да и сама программа сокращется.
Далее, зная N (номер искомого числа), легко вычисляется K - количество разрядов в нем: сперва записываем в K единицу, а потом увеличиваем, пока S[K] < N.
После этого я запоминал номера узлов каждого уровня (начиная с K-го и вверх), через которые нужно пройти, чтобы получить искомое. В результате получил массив A из K элементов.
Теперь, зная номера узлов в каждом уровне, легко определить путь прохода дерева с одновременным формированием числа. Для этого я просматривал массив A в прямом порядке (от 1 до K) и находил номера цифр ((A[i] - 1) mod T[i]) из строки W (в начале, перед первым шагом = '123456789'), добавляя их к результирующей строке Z и удаляя из W.
На первый взгляд все кажется громоздким, но на деле выходит достаточно коротенькая программка:
Код:
uses
crt;
var
i, k, n: longint;
a, t, f, s: array [1..10] of longint;
w, z: string;
begin
clrscr;
write('n = '); readln(n);
if (n > 9) then begin
fillchar(t, sizeof(t), 0); t[1] := 9;
fillchar(f, sizeof(f), 0); f[1] := t[1];
fillchar(s, sizeof(s), 0); s[1] := f[1];
for i := 2 to 10 do begin
t[i] := 11 - i;
f[i] := t[i] * f[pred(i)];
s[i] := f[i] + s[pred(i)];
end;
if n > s[10] then z := 'no solutions' else begin
k := 1;
while s[k] < n do inc(k);
fillchar(a, sizeof(a), 0);
for i := k downto 1 do begin
if i = k then a[i] := n - s[i - 1]
else a[i] := succ(pred(a[i + 1]) div t[i + 1]);
end;
w := '123456789';
z := '';
for i := 1 to k do begin
z := z + w[succ(pred(a[i]) mod t[i])];
delete(w, succ(pred(a[i]) mod t[i]), 1);
if i = 1 then w := '0' + w;
end;
end;
end else if n > 0 then str(n, z) else z := 'no solutions';
writeln('r = ', z);
readkey;
end.