Помощь - Поиск - Пользователи - Календарь
Полная версия: помогите!
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
T@ty@n@
М wacko.gif может кто занет как решать эти задачи, а то зачет не могу сдать.
1. дано натуральное к.напечатать к-ю цифру последовательности 12345678910111213, в которой выписаны подряд все натуральные числа.
2. дан текст.определить является ли он правильной десятичной записью целого числа.
klem4
Хм, второе, последнее предупреждение
 ! 
1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...

volvo
Ну, тему все одно за нарушение Правил закроют... Кстати, Поиск тоже неплохо использовать:

1) Олимпиадные задачи.
Вторая задача тоже решалась...
klem4
Мой вариант первой задачи:

function DigitInfo(const k: LongInt): Char;
var
temp, curr, digit_len, digit_owner_number, digit_group: LongInt;
digit_pred_group: LongInt;
s: String;
begin
digit_group := 9;
digit_pred_group := 0;
digit_len := 1;
temp := 9;

while (k > digit_group) do begin
inc(digit_len);
temp := 9 * digit_len * round(exp(pred(digit_len) * ln(10)));
digit_pred_group := digit_group;
digit_group := temp + digit_group;
end;

digit_owner_number := (k - digit_pred_group - 1) div digit_len + 1;
str(round(exp((digit_len - 1) * ln(10))) + digit_owner_number - 1, s);
DigitInfo := s[k - (digit_pred_group + digit_len * (digit_owner_number - 1) + 1) + 1];
end;

var
k: Integer;

begin
readln(k);
writeln(DigitInfo(k));
end.


T@ty@n@ Переименуй название темы ...
hardcase
Цитата(klem4 @ 13.06.2007 0:10) *
Мой вариант первой задачи:


А это мой.
Только целочисленная арифметика и никаких str. blum.gif
Код

function GetDigit(k: integer): integer;
var counter: integer;     // счетчик натуральных чисел
    number: integer;      // текущее разбираемое число
    needNewNumber: boolean; // флаг - "завершился ли разбор числа?"
    maxDecimalMask: integer;  // максимальная маска десятичного разряда
    nextDecimalMask: integer; //  maxDecimalMask * 10
    decimalMask: integer;     // текущая маска десятичного разряда

    procedure Init;
    begin
        counter := 0;
        maxDecimalMask := 1;
        nextDecimalMask := maxDecimalMask * 10;
        needNewNumber := true;
    end;

    function GetNextDigit: integer;
    var digit: integer;
    begin
        // получаем следующее натуральное число
        if needNewNumber then begin
            needNewNumber := false;
            inc(counter);
            number := counter;
            if (counter mod nextDecimalMask) = 0 then begin
                maxDecimalMask := nextDecimalMask;
                nextDecimalMask := maxDecimalMask * 10;
            end;
            // сбрасываем маску
            decimalMask := maxDecimalMask;
        end;
        // получаем число в разряде
        digit := number div decimalMask;
        number := number mod decimalMask;
        decimalMask := decimalMask div 10;
        // если маска нулевая, то мы разобрали число
        if decimalMask = 0 then
            needNewNumber := true;
        // возвращаем результат
        GetNextDigit := digit;
    end;

var i: integer;
    digit: integer;
begin
    Init;
    // тупо перебираем k-разрядов
    digit := 0;
    for i := 1 to k do
        digit := GetNextDigit;
    // возращаем результат
    GetDigit := digit;
end;

но с инвариантом ессно красивше получается.
klem4
У мну тоже без строк легко можно ...

round(exp((digit_len - 1) * ln(10))) + digit_owner_number - 1
- это число*, содержаще нужную цифру (при к = 188 или 189 число соодержащее цифру с номером к = 99)

digit_len
- количество разрядов в этом числе (2-3-4-5 значное)

k - (digit_pred_group + digit_len * (digit_owner_number - 1) + 1) + 1
- номер нужного разряда из этого числа*, я просто для удобства число в строку перевел в конце ... ;)

Может кто еще решения предложит ? Интересная задачка smile.gif
Malice
Цитата(klem4 @ 13.06.2007 8:50) *

Может кто еще решения предложит ? Интересная задачка smile.gif

Не догнал с похмелья почему нельзя сделать в лоб blink.gif :

function test (x:longint): char;
var i:longint;
s:string;
begin
i:=0;
repeat
inc (i); str (i,s);
if x<=length(s) then begin
test:=s[x]; x:=0; end else
x:=x-length(s);
until x=0;
end;



Проверка..
for i:=1 to 1000 do write (test(i));

ps без str - + div и mod.
klem4
да уж)) good.gif
hardcase
Цитата(Malice @ 13.06.2007 13:13) *

Не догнал с похмелья почему нельзя сделать в лоб blink.gif

Все познается в сравнении.
Как оно показало - сидение за компом до 3 ночи (я) и похмелье (Malice) ни к чему хорошему не приводят.

Решения "в лоб" редко бывают выигрышными.

Файло в аттаче - консоль на Делфи, сравнивает решения так как мы их запостили на форум.
kelm4 рвет всех good.gif

volvo
hardcase, а ВСЕ решения нельзя было потестить? rolleyes.gif По ссылке в 3-ем посте есть еще 2, кстати.
klem4
Цитата
По ссылке в 3-ем посте есть еще 2, кстати.


Ну один из них точно не прокатит, ибо там ограничение на длину строки ...

Цитата
Файло в аттаче - консоль на Делфи, сравнивает решения так как мы их запостили на форум.
kelm4 рвет всех


Неожиданно приятно smile.gif
ps никнейм мой чуть-чуть по другому пишется smile.gif
volvo
Андрей, есть просьба: то решение, которое я приводил - было ошибочным, вот корректно работающая версия:

function get_digit(n: longint): char;
var
i: longint;
digits: byte;
start_of, maximal: longint;
num_of_n, num_of_digit: integer;
s: string;
begin
digits := 1;
start_of := 0;

maximal := 9;
while n > digits * maximal + start_of do begin { <--- Строгое неравенство }
inc(digits); maximal := maximal * 10;
inc(start_of, pred(digits) * (maximal div 10));
end;
maximal := maximal div 10;

dec(n, start_of);
num_of_n := (n div digits) + byte((n mod digits) <> 0);
num_of_digit := n - digits * pred(num_of_n);

n := 1;
for i := digits downto 2 do n := n * 10;
str(n + pred(num_of_n), s);
get_digit := s[num_of_digit];
end;


исправь в топике "Олимпиадные задачи"...
мисс_граффити
Все, конечно, очень мило, но правила есть правила.
T@ty@n@ внимания на них (и на предупреждения) не обращает.
Тема закрыта...
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.