Cod sursa(job #1659173)

Utilizator hrazvanHarsan Razvan hrazvan Data 22 martie 2016 00:53:09
Problema Vanatoare Scor 0
Compilator c Status done
Runda Arhiva de probleme Marime 2.37 kb
#include <stdio.h>
#define MAXN 16
#define INF 2000000000
int len[(1 << MAXN)], prev[(1 << MAXN)], poz[(1 << MAXN)];
long long bm[(1 << MAXN)], bun[(1 << MAXN)];
int v[MAXN], c[MAXN];
int b[MAXN];
int min, p, cpoz;

inline long long modulo(long long a, long long b){
  a %= b;
  if(a < 0)
    return a + b;
  return a;
}

inline long long cmmdc(long long a, long long b){
  long long r;
  while(b > 0){
    r = modulo(a, b);
    a = b;
    b = r;
  }
  return a;
}

void euclid(long long a, long long b, long long *x, long long *y){
  if(b == 0){
    *x = 1;
    *y = 0;
  }
  else{
    long long x0, y0;
    euclid(b, modulo(a, b), &x0, &y0);
    *x = y0;
    *y = x0 - (a / b) * y0;
  }
}

inline void calc(int n, int t){
  int i, j, k;
  long long h, l, m, c1, aux, d;
  bm[0] = 1;
  for(i = 1; i < (1 << n); i++){
    j = 0;
    while((i & (1 << j)) == 0)
      j++;
    k = (i ^ (1 << j));
    if(bun[k] == -1)
      bun[i] = -1;
    else{
      d = cmmdc(bm[k], v[j]);
      bm[i] = bm[k] * v[j] / d;
      h = bm[i];
      if(modulo((c[j] - bun[k]), d) == 0){
        l = (c[j] - bun[k]) / d;
        euclid(bm[k], v[j], &c1, &aux);
        m = modulo(c1 * l, (h / bm[k]));
        bun[i] = bm[k] * m + bun[k];
        if(bun[i] > t)
          bun[i] = -1;
      }
      else
        bun[i] = -1;
    }
  }
}

void bkt(int s, int d, int x, int i){
  if(bun[x] != -1){
    if(x != 0 && min > len[i ^ x] + 1){
      min = len[i ^ x] + 1;
      p = i ^ x;
      cpoz = bun[x];
    }
    if(s <= d){
      x += (1 << b[s]);
      bkt(s + 1, d, x, i);
      x -= (1 << b[s]);
      bkt(s + 1, d, x, i);
    }
  }
}

int main(){
  FILE *in = fopen("vanatoare.in", "r");
  int n, t, i, j, cj, ci;
  fscanf(in, "%d%d", &n, &t);
  for(i = 0; i < n; i++)
    fscanf(in, "%d%d", &c[i], &v[i]);
  //calc(n, t);
  for(i = 1; i < (1 << n); i++){
    ci = i;
    j = 0;
    cj = 0;
    while(ci > 0){
      if(ci & 1){
        b[j] = cj;
        j++;
      }
      cj++;
      ci /= 2;
    }
    min = INF;
    bkt(0, j - 1, 0, i);
    len[i] = min;
    prev[i] = p;
    poz[i] = cpoz;
  }
  fclose(in);
  FILE *out = fopen("vanatoare.out", "w");
  fprintf(out, "%d\n", len[(1 << n) - 1]);
  i = (1 << n) - 1;
  while(i != 0){
    fprintf(out, "%d ", poz[i]);
    i = prev[i];
  }
  fclose(out);
  return 0;
}