P-е сочетание из N по K

Рейтинг: 0Ответов: 1Опубликовано: 26.01.2015

Задача:
Вводится n,k,p. Нужно вывести p-ое сочетание из n по k, причем гарантируется, что это сочетание существует.
Сочетания номеруются с 0.
Ограничения: 1<=n<=32; 0<=k<=n;
1 секунда, 256 мб

Т. к. простой перебор не заходит, я написал вот такой код, который выдает неверный ответ на паре тестов. В алгоритме ни я, ни мои знакомые ошибки не видят. Возможно, это какая-то специфическая ошибка для С++. Заранее спасибо.

Вот сам код:

#include <iostream>
#include <fstream>

using namespace std;

int mas[40];

long long C(int n,int k)
{
    if ((n==k) || (k==0)) {
        return 1;
    }
    if (k==1) {
        return n;
    }
    return C(n-1,k)+C(n-1,k-1);
}

int main()
{
    ifstream cin;
    ofstream cout;
    cin.open("comb.in");
    cout.open("comb.out");
    long long n,k,p,c,t,last=0;
    cin >> n >> k >> p;
    for (int i=1; i<=k; i++) {
        c=C(n-i,k-i);
        t=0;
        while (p>=c) {
            t++;
            p-=c;
            c=C(n-t-i,k-i);
        }
        cout << t+1+last << ' ';
        last+=t+1;
    }
    return 0;
}

Ответы

▲ 1

Я чуть-чуть изменил Ваш код:

#include <iostream>
//#include <fstream>

using namespace std;

int mas[40];

long long C(int n,int k)
{
    if ((n==k) || (k==0)) {
        return 1;
    }
    if (k==1) {
        return n;
    }
    return C(n-1,k)+C(n-1,k-1);
}

int main()
{
    long long n,k,p,c,t,last=0;
    cin >> n >> k >> p;
    for (int i=1; i<=k; i++) {
        for (int it = last + 1; it <= n; it++) {
            c = C(n - it, k - i);

            if (p <= c) {
                cout << it << " ";
                last = it;
                break;
            } else {
                p -= c;
            }

        }
    }
    return 0;
}