Submission #750984

#TimeUsernameProblemLanguageResultExecution timeMemory
750984puppyUnscrambling a Messy Bug (IOI16_messy)C++17
100 / 100
2 ms472 KiB
#include <vector> #include <iostream> #include "messy.h" using namespace std; int calc(int i, int j) { //i를 j번 비트까지 봤을 때 int ans = 0; for (int k = 6; k >= j; k--) ans += i & 1 << k; return ans; } std::vector<int> restore_permutation(int n, int w, int r) { string s(n, '0'); for (int i = 0; i <= 6; i++) { s[i] = '1'; add_element(s); s[i] = '0'; } for (int i = 1; i < n; i++) s[i] = '1'; add_element(s); for (int i = 1; i < n; i++) s[i] = '0'; s[0] = '1'; for (int i = 1; i <= 5; i++) { s[i] = '1'; add_element(s); } for (int i = 0; i <= 6; i++) s[i] = '0'; for (int i = 7; i < n; i++) { for (int j = 0; j < 7; j++) { if (i & (1 << j)) { s[i] = '1'; s[j] = '1'; add_element(s); s[i] = '0'; s[j] = '0'; } } } compile_set(); vector<int> p(n, -1); vector<int> lst; //일단 처음에 1인 애들을 다 찾으면 얘녜 p[i] = 0, 1, ..., 6임 for (int i = 0; i < n; i++) { s[i] = '1'; if (check_element(s)) { lst.push_back(i); } s[i] = '0'; } vector<int> rev(n); for (int i = 0; i < 7; i++) { for (int j = 0; j < n; j++) { if (lst[i] != j) s[j] = '1'; } if (check_element(s)) { rev[0] = lst[i]; p[lst[i]] = 0; } for (int j = 0; j < n; j++) s[j] = '0'; } s[rev[0]] = '1'; for (int i = 1; i <= 5; i++) { //i번째 거 알아내기: 지금까지 for (int j = 0; j < 7; j++) { if (p[lst[j]] != -1) continue; //j인지 테스트 s[lst[j]] = '1'; if (check_element(s)) { rev[i] = lst[j]; p[lst[j]] = i; } s[lst[j]] = '0'; } s[rev[i]] = '1'; } for (int j = 0; j < 7; j++) { if (p[lst[j]] == -1) { p[lst[j]] = 6; rev[6] = lst[j]; } } for (int i = 0; i < n; i++) s[i] = '0'; //이제 0부터 6번까지를 다 구함 vector<vector<int>> cnt(7, vector<int>(128)); //i가 등장했는가 여부: rev[i] 체크 //cnt[i][j]: i번 비트까지 봤을 때 j인 것이 몇 개인가 //ouc[i][j]: i번 비트까지 봤을 때 j인 것이 몇 개 나왔는가, 로 갈게요 for (int i = 7; i < n; i++) { for (int k = 6; k >= 0; k--) cnt[k][calc(i, k)]++; } for (int i = 0; i < n; i++) { if (p[i] != -1) continue; int ret = 0; for (int k = 6; k >= 0; k--) { if (cnt[k][ret+(1<<k)] == 0) { //비트 1 확정 cnt[k][ret]--; } else if (cnt[k][ret] == 0) { ret += (1<<k); cnt[k][ret]--; } else { s[i] = '1'; s[rev[k]] = '1'; if (check_element(s)) { ret += (1<<k); cnt[k][ret]--; } else { cnt[k][ret]--; } s[i] = '0'; s[rev[k]] = '0'; } //k번째 비트까지 봤을 때 ret + (1 << k)인 것의 개수가 0개 남았거나 //k번째 비트까지 봤을 때 ret인 것의 개수가 0개 남았는지 체크 } //i번의 원래 번호가 ret였다 rev[ret] = i; p[i] = ret; } return p; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...