답안 #874263

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
874263 2023-11-16T14:46:20 Z LucaLucaM Super Dango Maker (JOI22_dango3) C++17
100 / 100
2634 ms 1156 KB
#include "dango3.h"
#ifdef LOCAL
#include "grader.cpp"
#endif // LOCAL

#include <vector>
#include <random>
#include <algorithm>
#include <functional>
#include <cassert>
#include <iostream>

std::mt19937 rng(3192702);

void Solve(int n, int m) {
  /**

  sol in O(n * m^2) query uri:

  pornesc cu toate valorile ramase si de fiecare data incerc sa scot cate 1

  **/

  std::vector<int> id(n * m + 1);
  for (int i = 1; i <= n * m; i++) {
    id[i] = i;
  }
  shuffle(id.begin() + 1, id.end(), rng);

  int cate = 0;

  auto query = [&] (std::vector<int> v) {
    std::vector<int> w;
    for (const auto &x : v) {
      w.push_back(id[x]);
    }
    cate++;
    return Query(w);
  };
  auto answer = [&] (std::vector<int> v) {
    std::vector<int> w;
    for (const auto &x : v) {
      w.push_back(id[x]);
    }
    Answer(w);
  };

  std::function<std::vector<int>(std::vector<int>)> exclude = [&] (std::vector<int> v) {
    bool dont[n * m + 1] = {};
    for (const auto &x : v) {
      dont[x] = true;
    }
    std::vector<int> w;
    for (int i = 1; i <= n * m; i++) {
      if (!dont[i]) {
        w.push_back(i);
      }
    }
    return w;
  };

  bool taken[n * m + 1] = {};

  int SZ = 50'000 / m;

  for (int rep = 0; rep < m; rep++) {
    std::vector<int> cand;
    for (int i = 1; i <= n * m; i++) {
      if (!taken[i]) {
        cand.push_back(i);
      }
    }
    std::vector<int> idk;
    do {
      shuffle(cand.begin(), cand.end(), rng);
      idk = cand;
      if ((int) idk.size() > SZ) {
        idk.resize(SZ);
      }
    } while (query(idk) == 0);
    cand = idk;
    std::vector<int> ret;
    ret.push_back(cand[0]);
    int qq = query(exclude(ret));
    for (int i = 1; i < (int) cand.size() && (int) ret.size() < n; i++) {
      std::vector<int> nw = ret;
      nw.push_back(cand[i]);
      if (qq == query(exclude(nw))) {
        ret.push_back(cand[i]);
      }
    }
//    std::cout << "! " << (int) ret.size() << '\n';
    answer(ret);
    for (const auto &x : ret) {
      taken[x] = true;
    }
  }

  assert(cate <= 50'000);

}
/**


3 2
3 3 1 2 1 2

4 4
2 2 3 2 4 4 3 2 3 1 1 3 4 1 4 1


**/
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
3 Correct 0 ms 348 KB Output is correct
4 Correct 0 ms 600 KB Output is correct
5 Correct 0 ms 348 KB Output is correct
6 Correct 0 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 17 ms 348 KB Output is correct
2 Correct 17 ms 348 KB Output is correct
3 Correct 18 ms 548 KB Output is correct
4 Correct 18 ms 344 KB Output is correct
5 Correct 16 ms 348 KB Output is correct
6 Correct 17 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 577 ms 716 KB Output is correct
2 Correct 591 ms 696 KB Output is correct
3 Correct 529 ms 700 KB Output is correct
4 Correct 548 ms 704 KB Output is correct
5 Correct 580 ms 692 KB Output is correct
6 Correct 590 ms 700 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2355 ms 916 KB Output is correct
2 Correct 2504 ms 1072 KB Output is correct
3 Correct 2502 ms 1156 KB Output is correct
4 Correct 2593 ms 1048 KB Output is correct
5 Correct 2550 ms 948 KB Output is correct
6 Correct 2634 ms 1092 KB Output is correct