Prateek Krishna Ответов: 3

Почему он показывает исключение с плавающей запятой (SIGFPE).


Задача состоит в том, чтобы вычислить комбинации(nCr). пользователь должен ввести нет тестовых случаев , число n и число r.

Ввод:
Первая строка содержит количество тестов тестов т. Т следовать. Каждый тестовый набор содержит 1 строку входных данных, содержащую 2 целых числа n и r, разделенных пробелом.

Выход:
Для каждого тестового случая в новой строке найдите nCr. Модуль вывода на 109+7.

Ограничения:
1 <= T <= 50
1<= n <= 103
1<= r <=800 ...

Что я уже пробовал:

#include <bits/stdc++.h>
using namespace std;

int main() {
int t;
cin>>t;
while(t--)
{
    int n,r;
    cin>>n>>r;
    if(r>n)
    cout<<"0"<<endl;
    else if(r==1)
    cout<<n<<endl;
    else if(r==n)
    cout<<"1"<<endl;
    else if(n-r==1)
    cout<<n<<endl;
    else
    {
        int i,j;
        long  int res;
        long  int num=n;
        for(i=n-1;i>=(n-r+1);i--)
            num*=i;
            long int ch=(pow(10,9)+7);
        long  int den=r;
        for(i=r-1;i>=2;i--)
           den*=i;
           if((num/den)<ch)
           res=(num/den);
           else if ((num/den)==ch)
           res=0;
           else
           res=((num/den)%ch);
           cout<<res<<endl;
    }
}
	return 0;
}

Rick York

Одна вещь, которая может очень помочь читабельности кода, - это правильно отступить ваш код. Тогда вы сможете лучше видеть иерархию и протяженность циклов. В вашем коде трудно понять, где вы подразумеваете расширение циклов for. Точно так же, как ifs и elses, цикл for расширяется для одного оператора, если только он не имеет фигурных скобок. Мне кажется, что ваши петли for нуждаются в некоторых скобках. Это хорошая привычка всегда добавлять их, потому что тогда вам будет легче добавлять операторы в цикл.

3 Ответов

Рейтинг:
1

KarstenK

Причиной SIGPFE является ошибка в коде, часто это деление с 0 в качестве делителя.

Я рекомендую использовать отладчик и тестировать до 0 перед разделением.


Рейтинг:
0

Patrice T

Научитесь правильно делать отступы в вашем коде, это покажет его структуру, и это поможет чтению и пониманию. Это также помогает выявлять структурные ошибки.

#include <bits/stdc++.h>
using namespace std;

int main() {
    int t;
    cin>>t;
    while(t--)
    {
        int n,r;
        cin>>n>>r;
        if(r>n)
            cout<<"0"<<endl;
        else if(r==1)
            cout<<n<<endl;
        else if(r==n)
            cout<<"1"<<endl;
        else if(n-r==1)
            cout<<n<<endl;
        else
        {
            int i,j;
            long  int res;
            long  int num=n;
            for(i=n-1;i>=(n-r+1);i--)
                num*=i;
            long int ch=(pow(10,9)+7);
            long  int den=r;
            for(i=r-1;i>=2;i--)
               den*=i;
           if((num/den)<ch)
               res=(num/den);
           else if ((num/den)==ch)
               res=0;
           else
               res=((num/den)%ch);
           cout<<res<<endl;
        }
    }
        return 0;
}

Стиль отступа - Википедия[^]

Профессиональные редакторы программистов имеют эту функцию и другие, такие как сопоставление скобок и подсветка синтаксиса.
Блокнот++ Главная Страница[^]
личные[^]
Цитата:
Почему он показывает исключение с плавающей запятой (SIGFPE).

Потому что ваш алгоритм приводит к огромным целым числам, которые выходят за пределы целых чисел.
- Некоторые уточнения в вашем алгоритме могут предотвратить слишком быстрый рост целых чисел. изучите задачу на примерах: возьмите набор из 10 частей и посмотрите, как работает математика, если вы берете 1, 2, 3 ... Сравните результаты, как вы получите ответ ...
- Использование bigint (бесконечных целых чисел) также является решением проблемы.


Prateek Krishna

как я должен решить этот вопрос? - я не получаю никакого представления .

Рейтинг:
0

OriginalGriff

Компиляция не означает, что ваш код верен! :смеяться:
Подумайте о процессе разработки как о написании электронного письма: успешная компиляция означает, что вы написали письмо на правильном языке - например, на английском, а не на немецком, - а не то, что письмо содержало сообщение, которое вы хотели отправить.

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

Начните с рассмотрения того, что он делает, и как это отличается от того, что вы хотели. Это важно, потому что это дает вам информацию о том, почему он это делает. Например, если программа предназначена для того, чтобы позволить пользователю ввести число, а затем удвоить его и напечатать ответ, то если бы ввод / вывод был таким:

Input   Expected output    Actual output
  1            2                 1
  2            4                 4
  3            6                 9
  4            8                16
Тогда совершенно очевидно, что проблема заключается в бите, который удваивает его - он не прибавляет себя к себе или умножает его на 2, он умножает его на себя и возвращает квадрат входного сигнала.
Таким образом, вы можете посмотреть на код, и очевидно, что он находится где-то здесь:
int Double(int value)
   {
   return value * value;
   }

Как только у вас появится идея, что может пойти не так, начните использовать отладчик, чтобы выяснить, почему. Поместите точку останова в первую строку функции и запустите приложение. Когда он достигнет точки останова, отладчик остановится и передаст управление вам. Теперь вы можете запускать свой код построчно (так называемый "одноступенчатый") и просматривать (или даже изменять) содержимое переменных по мере необходимости (черт возьми, вы даже можете изменить код и повторить попытку, если вам это нужно).
Подумайте о том, что должна делать каждая строка кода перед ее выполнением, и сравните это с тем, что она действительно делала, когда вы использовали кнопку "Step over" для выполнения каждой строки по очереди. Он сделал то, что вы ожидали? Если да, то переходите к следующей строке.
Если нет, то почему? Чем это отличается?
Надеюсь, это поможет вам определить, в какой части этого кода есть проблема и в чем она заключается.
Это навык, и его стоит развивать, поскольку он помогает вам как в реальном мире, так и в развитии. И, как и все навыки, он только улучшается при использовании!