Cod sursa(job #2273782)

Utilizator mouse_wirelessMouse Wireless mouse_wireless Data 31 octombrie 2018 21:56:05
Problema Lacate Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.09 kb
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define mp make_pair
#define CHECK(x) if(!(x)) return false;
#define CHECKRET(x, y) if(!(x)) return (y);
#define SKIP(x) if((x)) continue;
typedef pair<int, int> pii;

#ifdef INFOARENA
#define ProblemName "lacate"
#else
#define ProblemName "fis"
#endif

#define InFile ProblemName ".in"
#define OuFile ProblemName ".out"

const int MAXN = 300;
int st[MAXN];

bool bkt(int N, int L, int lvl = 0) {
  if (lvl == N) {
    //check if any group of N can do it
    for (int ex = 0; ex < N; ++ex) {
      int msk = 0;
      for (int i = 0; i < N; ++i)
        if (i != ex) msk |= st[i];
      CHECK(msk == (1 << L) - 1);
    }
    //check if any group of N - 2 cannot do it
    for (int ex1 = 0; ex1 < N; ++ex1)
      for (int ex2 = ex1 + 1; ex2 < N; ++ex2) {
        int msk = 0;
        for (int i = 0; i < N; ++i)
          if (i != ex1 && i != ex2) msk |= st[i];
        CHECK(msk != (1 << L) - 1);
      }
    return true;
  }
  for (int msk = st[lvl - 1]; msk < (1 << L); ++msk) {
    st[lvl] = msk;
    SKIP(__builtin_popcount(msk) != __builtin_popcount(st[0]));
    if (bkt(N, L, lvl + 1)) return true;
  }
  return false;
}

bool bkt0(int N, int L) {
  for (int i = 1; i < L; ++i) {
    st[0] = (1 << i) - 1;
    if (bkt(N, L, 1))
      return true;
  }
  return false;
}

void brute(int N) {
  for (int L = 1; ; ++L) {
    printf("Checking ... %d\n", L);
    SKIP(!bkt0(N, L));
    printf("Found a solution! %d\n", L);
    for (int i = 0; i < N; ++i) {
      for (int j = 0; j < L; ++j)
        printf((st[i] & (1 << j)) ? "1 " : "0 ");
      puts("");
    }
    return;
  }
}

int main() {
  //brute(4); return 0;
  assert(freopen(InFile, "r", stdin));
  assert(freopen(OuFile, "w", stdout));
  int N;
  scanf("%d", &N);
  vector< vector<int> > v(N);
  printf("%d %d\n", N * (N - 1) / 2, N - 1);
  int k = 0;
  for (int i = 0; i < N; ++i)
    for (int j = i + 1; j < N; ++j) {
      v[i].push_back(k);
      v[j].push_back(k);
      ++k;
    }
  for (int i = 0; i < N; ++i) {
    for (const auto &it : v[i])
      printf("%d ", it + 1);
    puts("");
  }
  return 0;
}