Имя пользователя:
Пароль:
 

Показать сообщение отдельно

редкий гость


Сообщения: 1696
Благодарности: 44

Профиль | Сайт | Отправить PM | Цитировать


Если очень хочется извратиться и впихнуть всё в 4кб, то можно закодировать таблицу в виде сдвигов между соседними значениями. Т.к. мы умножаем максимум на 2000, то длина изменяется не более, чем на 4 знака каждый раз; но не менее, чем на один. Для хранения этой информации достаточно 2 бит. А для хранения всех сдвигов - 4000 бит, которые можно записать в виде строки (если использовать только печатные символы из нижней половины ascii, чтобы можно было вставить в исходный текст без изменений) всего в 4000/log2(64)=667 символов, ещё 3кб на код останется . И потом декодировать оттуда нужную информацию небольшим кусочком кода.

Всё решение будет типа такого:
Код: Выделить весь код
unsigned char[] diff_table="blah-blah blah..."; //667 символов таблицы.

// получить i-й сдвиг из таблицы.
int getDiff(int i) {
    unsigned char c = diff_table[i/6] - 32;
    int diff = (c >> ((i%6)*2)) & 3; 
    return diff;
}
// ....
char fac_str[10000];
cin >> fac_str; // зачитываем факториал, _как строку_

int need_len = strlen(fac_str); // длина факториала, для которого надо найти n
int n = 0; // ответ будет здесь
if (need_len <= 8) {
    // n <= 10, тупо подбираем
    int facn = 1;
    int fac = atoi(fac_str);
    for (n = 1; facn < fac; ++n) {
        facn *= n;
    }
} else {
    int len = 8; // длина факториала 10
    // начинаем подбирать с 11
    for (n = 11; len < need_len; ++n) {
        len += getDiff(n);
    }
}
А можно, всё-таки, честно запрограммировать длинное умножение и не париться с извращениями. Ссылку в яндекс, где объясняется, как правильно умножать длинные числа, я уже бросал.

-------
http://ivank.ru


Последний раз редактировалось ivank, 01-06-2008 в 19:19.


Отправлено: 17:52, 01-06-2008 | #23