Cod sursa(job #892748)

Utilizator cruceruvladCruceru Vlad cruceruvlad Data 26 februarie 2013 11:31:41
Problema Vanatoare Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.15 kb
#include <stdio.h>
#include <vector>
#include <algorithm>

using namespace std;

#define pt(i) (1<<(i))
#define FOR(i,s,d) for(i=(s);i<(d);++i)
#define f first
#define s second

int cmmdc(int i,int j)
{
    while(i&&j)
        if(i>=j)
            i%=j;
        else
            j%=i;
    return i^j;
}

typedef long long lint;

int n,D,dt[pt(16)];
lint cmmmc[pt(16)];
pair<int,int> P[16],A[pt(16)];

void afis(int i)
{
    if(i)
    {
        afis(i^A[i].s);
        printf("%d ",dt[A[i].s]);
    }
}

void baga(int i,int mask,int ask)
{
    if(dt[mask]>D) return ;
    if(i==n)
    {
        if(A[ask^mask].f+1<A[ask].f) A[ask].f=A[mask^ask].f+1,A[ask].s=mask;
        return ;
    }
    baga(i+1,mask,ask);
    if(pt(i)&ask)
        baga(i+1,mask|pt(i),ask);
}

void doit(int i,int mask,int ask)
{
    if(dt[ask]>D) return ;
    if(i==n)
    {
        if(mask && A[ask^mask].f+1<A[mask].f)
            A[mask].f=A[mask^ask].f+1,A[mask].s=ask;
        return ;
    }
    doit(i+1,mask,ask);
    doit(i+1,mask|pt(i),ask);
    doit(i+1,mask|pt(i),ask|pt(i));
}

int getd(int a,int b,int x,int y)
{
    if(a<x)
        return getd(x,y,a,b);
    if((b-y)%cmmdc(a,x)!=0) return D+1;
    int aux=b;
    for(;aux<=D && aux % x!=y;)
        if(aux<=D-a)
            aux+=a;
        else
            aux=D+1;
    return aux;
}

int main()
{
    int i,j,k;
    freopen("vanatoare.in","r",stdin);
    freopen("vanatoare.out","w",stdout);
    scanf("%d %d",&n,&D);
    FOR(i,0,n)
        scanf("%d %d",&P[i].s,&P[i].f);
    sort(P,P+n);
    //reverse(P,P+n);
    cmmmc[0]=1,dt[0]=0;

    FOR(i,1,pt(n))
    {
        A[i].f=n+1;
        FOR(j,0,n) if(pt(j)&i) break;
        k=i^pt(j);
        cmmmc[i] = cmmmc[k]/cmmdc(cmmmc[k],P[j].f)*P[j].f;
        if(cmmmc[i]>D) cmmmc[i]=D+1;
        dt[i]=getd(cmmmc[k],dt[k],P[j].f,P[j].s);
    }
    doit(0,0,0);
//  FOR(i,1,pt(n))
//      baga(0,0,i);
/*  for(j=i;j;j=(j-1)&i)
            if(dt[j]<=D && A[i].f>A[i^j].f+1)
                A[i].f=A[i^j].f+1,A[i].s=j;*/
    printf("%d\n",A[pt(n)-1].f);
    afis(pt(n)-1);
    printf("\n");
    return 0;
}