Cod sursa(job #2643425)

Utilizator mjmilan11Mujdar Milan mjmilan11 Data 19 august 2020 19:56:55
Problema Vanatoare Scor 25
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.92 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("vanatoare.in");
ofstream fout("vanatoare.out");
const int NMAX = 16;
pair <int,int> v[NMAX],info[1<<NMAX];
int dp[1<<NMAX],lant[1<<NMAX],rasp[NMAX],n,t;
int euclid(int a,int b,long long &x,long long &y){
    if(b==0){
        x=1;
        y=0;
        return a;
    }
    long long x2,y2;
    int d=euclid(b,a%b,x2,y2);
    x=y2;
    y=x2-(a/b)*y2;
    return d;
}
pair<int,int> TCR(pair<int,int> a1,pair<int,int> a2){
    if(a1.second>=t+1 and a2.second>=t+1){
        if(a1.first!=a2.first) return make_pair(-1,-1);
                               return make_pair(a1.first,t+1);
    }
    if(a2.second>=t+1) swap(a1,a2);
    if(a1.second>=t+1){
        if(a1.first%a2.second!=a2.first) return make_pair(-1,-1);
                                         return a1;
    }
    long long c1,c2;
    int d=euclid(a1.second,a2.second,c1,c2);
    int h=min(a1.second*a2.second/d,(t+1));
    if((a2.first-a1.first)%d!=0) return make_pair(-1,-1);
    int l=(a2.first-a1.first)/d;
    int m1=(c1*l)%(a2.second/d);
    if(m1<0) m1+=a2.second/d;
    long long x=a1.second*m1+a1.first;
    if(h<=t){
        x%=h;
        return make_pair(x,h);
    } else {
        x%=(a1.second*a2.second/d);
        if(x<=t) return make_pair(x,h);
                 return make_pair(-1,-1);
    }
}
int main()
{
    fin >> n >> t;
    for(int i=0;i<n;i++) fin >> v[i].first >> v[i].second;
    info[0]={0,1};
    for(int config=1;config<(1<<n);config++){
        int nr_bits=0,bit=0;
        for(int i=0;i<n;i++){
            if((config&(1<<i))!=0){
                nr_bits++;
                bit=i;
            }
        }
        if(nr_bits==1){
            if(v[bit].first<=t) info[config]=v[bit];
            else                   info[config]=make_pair(-1,-1);
            continue;
        }
        bool ok=false;
        for(int i=0;i<n;i++){
            if(ok==true) break;
            if(((1<<i)&config)!=0 && info[config^(1<<i)].first==-1){
                    ok=true;
            }
        }
        if(ok==true){
            info[config]=make_pair(-1,-1);
            continue;
        }
        info[config]=TCR(v[bit],info[config^(1<<bit)]);
    }
    for(int config=1;config<(1<<n);config++){
        dp[config]=n+1;
        for(int config_2=config;config_2!=0;config_2=((config_2-1)&config)){
            if(dp[config^config_2]<=n && info[config_2].first!=-1){
                if(dp[config]>dp[config^config_2]+1){
                   dp[config]=dp[config^config_2]+1;
                   lant[config]=config_2;
                }
            }
        }
    }
    fout << dp[(1<<n)-1] << '\n';
    int dim_rasp=0;
    for(int config=(1<<n)-1;config!=0;config=(config^lant[config]))
        rasp[++dim_rasp]=info[lant[config]].first;
    sort(rasp+1,rasp+dim_rasp+1);
    for(int i=1;i<=dim_rasp;i++) fout << rasp[i] << ' ';
    return 0;
}