Cod sursa(job #2311605)

Utilizator AlexPop28Pop Alex-Nicolae AlexPop28 Data 3 ianuarie 2019 14:55:20
Problema Pavare2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.81 kb
#include <bits/stdc++.h>
#define all(cont) cont.begin(), cont.end()
#define pb push_back
#define fi first
#define se second
#define DEBUG(x) cerr << (#x) << ": " << (x) << '\n'

using namespace std;

typedef pair <int, int> pii;
typedef vector <int> vi;
typedef long long ll;
typedef unsigned long long ull;


struct BigInteger {
  static const int NMAX = 100;
  static const int BASE = 10;
  short v[NMAX];
  BigInteger () {
    memset (v, 0, sizeof (v));
  }
  void print ();
  void operator = (int x);
  void operator = (BigInteger other);
  BigInteger operator + (BigInteger &other);
  BigInteger operator * (int x);
  BigInteger operator - (BigInteger &other);
  BigInteger operator / (int x);
  bool operator < (BigInteger &other);
  bool operator <= (BigInteger &other);
  bool operator >= (BigInteger &other);
};

void BigInteger::print () {
  for (int i = v[0]; i >= 1; --i) {
    printf ("%d", v[i]);
  }
}

void BigInteger::operator = (int x) {
  v[0] = 0;

  while (x) {
    v[++v[0]] = x % BASE;
    x /= BASE;
  }

//    return *this;
}

void BigInteger::operator = (BigInteger other) {
  for (int i = 0; i <= other.v[0]; ++i) {
    v[i] = other.v[i];
  }

//    return *this;
}

BigInteger sum; // only here
BigInteger BigInteger::operator + (BigInteger &other) {
  sum = 0;
  int temp = 0, i;

  for (i = 1; i <= v[0] || i <= other.v[0] || temp; ++i, temp /= BASE) {
    sum.v[i] = (temp += v[i] + other.v[i]) % BASE;
  }

  sum.v[0] = i - 1;
  return sum;
}

BigInteger mult; // only here
BigInteger BigInteger::operator * (int x) {
  mult = 0;
  int temp = 0, i;

  for (i = 1; i <= v[0] || temp; ++i, temp /= BASE) {
    mult.v[i] = (temp += v[i] * x) % BASE;
  }

  mult.v[0] = i - 1;
  return mult;
}

BigInteger diff;
BigInteger BigInteger::operator - (BigInteger &other) {
  diff = *this;
  int temp = 0, i;
  for (i = 1; i <= diff.v[0]; ++i) {
    diff.v[i] -= ((i <= other.v[0]) ? other.v[i] : 0) + temp;
    diff.v[i] += (temp = diff.v[i] < 0) * BASE;
  }

  for (; diff.v[0] > 1 && !diff.v[diff.v[0]]; --diff.v[0]);
  return diff;
}

BigInteger divv;
BigInteger BigInteger::operator / (int x) {
  divv = *this;
  int temp = 0, i;
  for (i = divv.v[0]; i > 0; --i, temp %= x) {
    divv.v[i] = (temp = temp * BASE + divv.v[i]) / x;
  }
  for (; divv.v[0] > 1 && !divv.v[divv.v[0]]; --divv.v[0]);
  return divv;
}

bool BigInteger::operator < (BigInteger &other) {
  if (v[0] != other.v[0]) {
    return v[0] < other.v[0];
  }

  for (int i = v[0]; i >= 1; --i) {
    if (v[i] != other.v[i]) {
      return v[i] < other.v[i];
    }
  }
  return false; // "="
}

bool BigInteger::operator <= (BigInteger &other) {
  if (v[0] != other.v[0]) {
    return v[0] < other.v[0];
  }

  for (int i = v[0]; i >= 1; --i) {
    if (v[i] != other.v[i]) {
      return v[i] < other.v[i];
    }
  }
  return true; // "="
}

bool BigInteger::operator >= (BigInteger &other) {
  return other <= *this;
}

const int NMAX = 105;

int n, a, b;
char aux[NMAX];
BigInteger dp[NMAX][NMAX][2];
BigInteger idx, ans;

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
#ifdef LOCAL_DEFINE
  freopen (".in", "r", stdin);
#endif

  freopen ("pavare2.in", "r", stdin);
  freopen ("pavare2.out", "w", stdout);

  scanf ("%d %d %d\n", &n, &a, &b);
  scanf ("%s", aux + 1);
  idx.v[0] = strlen (aux + 1);
  for (int i = 1; i <= idx.v[0]; ++i) {
    idx.v[i] = aux[idx.v[0] - i + 1] - '0';
  }

  dp[0][0][0] = 1;
  dp[0][0][1] = 1;

  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= i && j <= a; ++j) {
      dp[i][j][0] = dp[i][j][0] + dp[i - j][0][0];
      dp[i][0][1] = dp[i][0][1] + dp[i][j][0];
    }
    for (int j = 1; j <= i && j <= b; ++j) {
      dp[i][j][1] = dp[i][j][1] + dp[i - j][0][1];
      dp[i][0][0] = dp[i][0][0] + dp[i][j][1];
    }
  }

  ans = dp[n][0][0] + dp[n][0][1];

  ans.print();
  printf ("\n");

  int rem = n;
  bool zeros = true;
  while (rem) {
    if (zeros) {
      if (dp[rem][0][1] < idx) {
        idx = idx - dp[rem][0][1];
      } else {
        for (int i = min (rem, a); i >= 1; --i) {
          if (dp[rem][i][0] < idx) {
            idx = idx - dp[rem][i][0];
          } else {
            for (int j = 1; j <= i; ++j) printf ("0");
            rem -= i;
            break;
          }
        }
      }
    } else {
      if (dp[rem][0][0] < idx) {
        idx = idx - dp[rem][0][0];
      } else {
        for (int i = 1; i <= min (b, rem); ++i) {
          if (dp[rem][i][1] < idx) {
            idx = idx - dp[rem][i][1];
          } else {
            for (int j = 1; j <= i; ++j) printf ("1");
            rem -= i;
            break;
          }
        }
      }
    }
    zeros ^= 1;
  }


  fclose (stdin);
  fclose (stdout);
  return 0;
}