Cod sursa(job #1775959)

Utilizator iordache.bogdanIordache Ioan-Bogdan iordache.bogdan Data 10 octombrie 2016 20:36:33
Problema Vanatoare Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.19 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <iostream>

using namespace std;

ifstream fin("vanatoare.in");
ofstream fout("vanatoare.out");

const int dim = 16;

int n, t;
pair<int, int> pigs[dim];

pair<int, int> prec[1 << dim];
int dp[1 << dim], parent[1 << dim];

int GCD(int a, int b, long long& x, long long& y) {

    if (!b) {
        x = 1, y = 0;
        return a;
    }

    long long xa, ya;
    int d = GCD(b, a % b, xa, ya);

    x = ya;
    y = xa - (a/b) * ya;
    return d;

}

inline pair<int, int> CTR(pair<int, int> a, pair<int, int> b) {

    if (a.second == t + 1 && b.second == t + 1) {
        if (a.first != b.first)
            return make_pair(-1, -1);
        else
            return make_pair(a.first, t + 1);
    }

    if (b.second == t + 1)
        swap(a, b);

    if (a.second == t + 1) {
        if (a.first % b.second != b.first)
            return make_pair(-1, -1);
        else
            return a;
    }

    long long c1, c2;
    int d = GCD(a.second, b.second, c1, c2);

    if ((b.first - a.first) % d)
        return {-1, -1};

    int h = min(1LL * (t + 1), 1LL * a.second * b.second / d);

    int l = (b.first - a.first)/d;
    int m1 = (1LL * c1 * l) % (b.second / d);
    if (m1 < 0) m1 += b.second / d;

    long long x = 1LL * a.second * m1 + a.first;

    if (h <= t) {
        x %= h;
        return make_pair(x, h);
    }
    else {
        x %= (1LL * a.second * b.second / d);
        if (x <= t)
            return make_pair(x, h);
        else
            return make_pair(-1, -1);
    }

}

int main() {

    fin >> n >> t;
    for (int i = 0; i < n; ++i)
        fin >> pigs[i].first >> pigs[i].second;

    prec[0] = {0, 1};
    for (int config = 1; config < (1 << n); ++config) {

        int bitCnt = 0, bit = 0;
        for (int i = 0; i < n; ++i)
           if ((1 << i) & config)
              bitCnt++, bit = i;

        if (bitCnt == 1) {
            if (pigs[bit].first <= t)
                prec[config] = pigs[bit];
            else
                prec[config] = {-1, -1};
            continue;
        }

        bool ok = true;
        for (int i = 0; i < n && ok; ++i)
            if (((1 << i) & config))
                if (prec[config ^ (1 << i)].first == -1)
                    ok = false;

        if (!ok) {
            prec[config] = {-1, -1};
            continue;
        }

        prec[config] = CTR(pigs[bit], prec[config ^ (1 << bit)]);

    }

    for (int config = 1; config < (1 << n); ++config) {

        dp[config] = n + 1;

        for (int oldConfig = config; oldConfig; oldConfig = ((oldConfig - 1) & config))
            if (dp[config ^ oldConfig] <= n && prec[oldConfig].first != -1)
                if (dp[config] > dp[config ^ oldConfig] + 1) {
                    dp[config] = dp[config ^ oldConfig] + 1;
                    parent[config] = oldConfig;
                }

    }

    fout << dp[(1 << n) - 1] << '\n';

    vector<int> sol;
    for (int config = (1 << n) - 1; config; config = (config ^ parent[config]))
        sol.push_back(prec[parent[config]].first);

    sort(sol.begin(), sol.end());

    for (auto it : sol)
        fout<< it << ' ';
    fout << '\n';

    return 0;

}

//Trust me, I'm the Doctor!