Задача для начинающих

Задача для начинающих

Доброго времени суток!
Я тут было зашел на Timus Online Judge :), гляжу, а там Череп и porshe задачи решают ;)
Думаю, решу и я, простенькую, для начинающих...
Но наверное, я что-то не понял :(( и где-то туплю.
Задача здесь, мои логические суждения и код прилагаются.
А именно:
1. Входной поток <= 256 КБ;
2. Создаю массив значений типа double размером 256000 / 8 = 32000;
Ну а дальше все проще простого, как мне показалось...
3. Читаем из потока в переменную типа unsigned long long для цифр 10^18, нахожу корень и присваиваю элементам массива;
4. Вывожу значения массива в обратном порядке.
У меня все работает.
Вердикт Timus — Wrong answer.

ВОПРОС: Где же я туплю? :)

#include <iostream>
#include <cmath>
#include <iomanip>

int main()
{
    using namespace std;

    unsigned long long n = 0;
    double arr[32000];
    double*a = arr;

    cin >> n;
    while (cin.good()){
        *a++ = sqrt(double(n));
        cin >> n;
    }
    while (--a != (arr - 1)){
        cout << setiosflags(ios::fixed)
                << setprecision(4) << *a << "\n";
    }


    return 0;
}

256kB это не 256000 байт, а 256 * 1024 = 262144, так как в одном КБ не 1000 байт, а 1024.

Вот тут, мне кажется, ошибка:

while ( --a != ( arr -1 ) )

По-моему, правильней будет так:

while ( a-- != arr )

И вообще, тут можно неплохо использовать vector.

С этой задачкой я вообще не стал мудрствовать:

#include <iostream>
#include <stack>
#include <math.h>
#include <iomanip>

using namespace std;

int main(int argc, char** argv) {

    stack<double> roots;
    double val;

    while(cin >> val) {
        roots.push(sqrt(val));
    }
    while (!roots.empty()) {
        cout << fixed << setprecision(4);
        cout << roots.top() << endl;
        roots.pop();
    }

    return 0;
}

Оно, конечно неоптимально, но вполне удовлетворительно (на вкус timus'а).

А твой вариант проходит в следующей редакции:

#include <iostream>
#include <cmath>
#include <iomanip>

double arr[131072];

int main()
{
    using namespace std;

    unsigned long long n = 0;
    double*a = arr;

    while (cin >> n){
        *a++ = sqrt(double(n));
    }
    while (a > arr){
        cout << setiosflags(ios::fixed)
                << setprecision(4) << *(--a) << "\n";
    }

    return 0;
}

Фраза

Размер входного потока не превышает 256 КБ.

видимо подразумевает полный размер входного потока, т.е. поток чисел может состоять из однозначных (1 байт) чисел плюс разделитель (+1 байт).

С входным потоком понятно, а почему при объявлении массива
double arr[131072]; в main()
— вердикт Stack overflow, а если его объявить глобально, то код проходит?

Ну естественно! Память для массива, который объявляется внутри функции (любой), выделяется из стека. А стек — не резиновый. (Посмотри на Timus'е — там где-то указан размер стека по умолчанию и директива для его увеличения.)

Если массив объявлен глобально, то память под него выделяется статически в сегменте данных при загрузке программы.

Но, даже если стек увеличивать директивой компилятора (точнее, линкера), то это плохая практика. Большие массивы лучше выделять либо статически, либо из кучи.

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.

Ответить

Вы можете использовать разметку markdown для оформления комментариев и постов. Используйте функцию предпросмотра для проверки корректности разметки.

Пожалуйста, оформляйте исходный код в соответствии с правилами разметки. Для того, чтобы вставить код в комментарий, скопируйте его в текстовое поле ниже, после чего выделите то, что скопировали и нажмите кнопку «код» в панели инструментов. Иначе ваш код может принять нечитаемый вид.

Либо производите оформление кода вручную, следующим образом:

``` #include <iostream> using namespace std; int main() { // ... } ```

Предпросмотр сообщения

Ваше сообщение пусто.