Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Dwumian Newtona

Ostatnio zmodyfikowano 2015-12-02 18:38
Autor Wiadomość
Anim
Temat założony przez niniejszego użytkownika
Dwumian Newtona
» 2015-12-02 14:29:54
cześć :) Po raz kolejny zwracam się z prośbą o analizę mojego kodu dotyczącego zadania ze spoja. Otóż poniżej mam kod, dla którego wyrzuca mi błąd, ale osobiście nie znajduje przypadku, dla którego ten kod nie działa - czyli zapewne dotyczy to jakiegoś wypadku trywialnego. Poniższy kod ma wyliczać wartość dwumianu newtona. Miałby ktoś chwilę cierpliwości i to przejrzał ? :)

C/C++
#include <iostream>

using namespace std;

unsigned long long int silnia( unsigned long long int & n, unsigned long long int & k );

int main()
{
    unsigned long long int t, n, k, x;
    cin >> t;
   
    while( t-- )
    {
        n = 0;
        k = 0;
        x = 0;
       
        cin >> n >> k;
       
        if( k > n )
        {
            cout << 0 << endl;
        }
        else if( k == 0 || k == n )
        {
            cout << 1 << endl;
        }
        else
        {
            x = silnia( n, k );
            cout << x << endl;
        }
    }
}

unsigned long long int silnia( unsigned long long int & n, unsigned long long int & k )
{
    unsigned long long int a = n - k;
    unsigned long long int b = 1;
    unsigned long long int j = 1;
    unsigned long long int i = 0;
    unsigned long long int e = 0;
   
    for( i = a + 1; i <= n; i++ )
    {
        b *= i;
        if( j < k )
        {
            if( b % j == 0 )
            {
                b = b / j;
                j = j + 1;
            }
        }
    }
    e = b / j;
    return e;
   
}
P-141283
mateczek
» 2015-12-02 14:57:15
Nie licz tego ze wzoru  na dwumian !!!! zbyt skomplikowany algorytm zbyt duże liczby !!!

Dwumian 40/3 będzie to 3 ostatnie liczby podzielone przez 3 pierwsze

40*39*38/(1*2*3)
co po dalszej optymalizacji można zapisać w 3 iteracjach
(40/1)*(39/2)*(38/3)
0: wynik =1
1: wynik=wynik*40/1
2: wynik=wynik*39/2
3  wynik=wynik*38/3

w trzeciej iteracji otrzymasz wynik dwumianu !!! (ale i ten algorytm mi nie przeszedł !!!)

dopiero po zastosowaniu innej właściwości dwumianu a mianowicie takiej że

dwumian(40/38) = dwumian(40/2) = 40*39/(1*2) pomogło !!!
P-141289
Anim
Temat założony przez niniejszego użytkownika
» 2015-12-02 16:18:13
Dzięki za pomysł, ale z tego co widzę, nie przejrzałeś mojego kodu, bo ja silni jako takiej tam praktycznie nie liczę ;p I bez problemu znajduję wynik chociażby dla (95 25)... i dużo bardziej "szerokie" wyniki, które zgadzają się z mathematicą.... tutaj chodzi o jakiś błąd w implementacji...

chociaż jak będę po raz kolejny musiał to pisać, to pewnie znów znajdę inną metodę, a wtedy przyda mi się Twoja wskazówka ;p
P-141300
mateczek
» 2015-12-02 16:57:08
sprawdź wynik kombinacji czy twój algortym sobie z nim poradzi w czasie 1s !!!

1000000000/999999999. wynik powinien być 1000000000

dla tego przykładu k = 999999999. Ale możesz zrobić k=1000000000-999999999 =1 i też będzie dobrze


P-141304
Anim
Temat założony przez niniejszego użytkownika
» 2015-12-02 17:09:58
aj, aj...ale masz rację :) korzę się :)

tylko w korzystaniu z własności, którą podałeś też musi być jakiś "złoty środek"... hm... w sensie czasami wygodniej skorzystać z wartości podstawowej... :)
P-141305
mateczek
» 2015-12-02 17:51:28
to sposób na wybranie optymalnego _k:
C/C++
int _k =(( n - k ) > k ) ? k
    :( n - k ); // kombinacje 5 z 6 jest tak samo jak 1 z 6

po prostu patrzysz co jest mniejsze k czy (n-k) i tą mniejszą wartość wybierasz !!!
P-141307
Anim
Temat założony przez niniejszego użytkownika
» 2015-12-02 17:59:39
własnie tak zrobiłem :) zadanie zaliczone :) uff ... 6 prób poszło :) dzięki wielkie
P-141309
mateczek
» 2015-12-02 18:38:46
Spoko!!! też się z tym bujałem!!! żeby nie było !!!
P-141315
« 1 »
  Strona 1 z 1