제출 #1343854

#제출 시각아이디문제언어결과실행 시간메모리
1343854SmuggingSpunMonster-Go (EGOI25_monstergo)C++20
100 / 100
4 ms588 KiB
#include<bits/stdc++.h>
#define taskname "C"
using namespace std;
typedef long long ll;
template<class T>bool minimize(T& a, T b){
  if(a > b){
    a = b;
    return true;
  }
  return false;
}
const int lim = 51;
ll Ckn[lim][lim];
vector<vector<int>>ans[lim];
int best_min[lim];
void merge(int a, int b, int c, int d){
  int x = a + b + c + d, sum_best_min = best_min[a] + best_min[b] + best_min[c] + best_min[d];
  if(x >= lim || sum_best_min >= lim || !minimize(best_min[x], sum_best_min)){
    return;
  }
  ans[x].clear();
  int offset = 0;
  for(int y : {a, b, c, d}){
    for(vector<int>& ve : ans[y]){
      ans[x].push_back(ve);
      for(int& i : ans[x].back()){
        i += offset;
      }
    }
    offset += best_min[y];
  }
}
int main(){
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	if(fopen(taskname".inp", "r")){
		freopen(taskname".inp", "r", stdin);
	}
  memset(Ckn, 0, sizeof(Ckn));
  fill(Ckn[0], Ckn[0] + lim, 1);
  for(int k = 1; k < lim; k++){
    for(int n = k; n < lim; n++){
      Ckn[k][n] = Ckn[k][n - 1] + Ckn[k - 1][n - 1];
    }
  }
  memset(best_min, 0x0f, sizeof(best_min));
  for(int d : {1, 2, 3, 4, 6}){
    for(int k = 1; 12 + d * k < lim && Ckn[k][12 / d + k] < lim; k++){
      int siz = 12 / d + k, n = Ckn[k][siz];
      if(minimize(best_min[n], siz * d)){
        vector<vector<int>>S(siz, vector<int>(d));
        for(int i = 0; i < siz; i++){
          iota(S[i].begin(), S[i].end(), i * d + 1);
        }      
        for(int mask = 0; mask < (1 << siz); mask++){
          if(__builtin_popcount(mask) == k){
            vector<int>t;
            for(int i = 0; i < siz; i++){
              if((mask >> i & 1) == 0){
                for(int& j : S[i]){
                  t.push_back(j);
                }
              }
            }
            ans[n].push_back(t);
          }
        }
      }
    }
  }  
  ans[1].push_back({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, best_min[1] = 12});
  ans[2].push_back({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});
  ans[2].push_back({13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, best_min[2] = 24});
  for(int a = best_min[0] = 0; a < lim; a++){
    for(int b = a; b < lim; b++){
      for(int c = b; c < lim; c++){
        for(int d = c; d < lim; d++){
          merge(a, b, c, d);
        }
      }
    }
  }
  int n;
  cin >> n;
  for(vector<int>& ve : ans[n]){
    for(int& x : ve){
      cout << x - 1 << " ";
    }
    cout << "\n";
  }
}

컴파일 시 표준 에러 (stderr) 메시지

Main.cpp: In function 'int main()':
Main.cpp:36:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   36 |                 freopen(taskname".inp", "r", stdin);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...