Submission #67393137
Source Code Expand
// #pragma GCC optimize("O3") // #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx") #include <assert.h> #include <algorithm> #include <bitset> #include <cassert> #include <cmath> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <set> #include <stack> #include <vector> #define dump(x) cerr << #x << " = " << (x) << endl; using namespace std; const int64_t CYCLES_PER_SEC = 2900000000; const double TIMELIMIT = 1.95; struct Timer { int64_t start; Timer() { reset(); } void reset() { start = getCycle(); } void plus(double a) { start -= (a * CYCLES_PER_SEC); } inline double get() { return (double)(getCycle() - start) / CYCLES_PER_SEC; } inline int64_t getCycle() { uint32_t low, high; __asm__ volatile("rdtsc" : "=a"(low), "=d"(high)); return ((int64_t)low) | ((int64_t)high << 32); } }; Timer timer; class XorShift { public: unsigned int x, y, z, w; double nL[65536]; XorShift() { init(); } void init() { x = 314159265; y = 358979323; z = 846264338; w = 327950288; double n = 1 / (double)(2 * 65536); for (int i = 0; i < 65536; i++) { nL[i] = log(((double)i / 65536) + n); } } inline unsigned int next() { unsigned int t = x ^ x << 11; x = y; y = z; z = w; return w = w ^ w >> 19 ^ t ^ t >> 8; } inline double nextLog() { return nL[next() & 0xFFFF]; } inline int nextInt(int m) { return (int)(next() % m); } int nextInt(int min, int max) { return min + nextInt(max - min + 1); } inline double nextDouble() { return (double)next() / ((long long)1 << 32); } }; XorShift rnd; const int N = 40; const int N2 = N * N; const int N2MMAX = N2 - (N2 / 10); struct FastSet2 { int N; int list[N2MMAX]; int pos[N2MMAX]; int sz; void init(int _N) { N = _N; sz = 0; for (int i = 0; i < N; i++) { pos[i] = list[i] = i; } } void insert_all() { sz = N; } int getAny() { return list[sz++]; } void insert(int a) { if (pos[a] >= sz) { pos[list[sz]] = pos[a]; swap(list[pos[a]], list[sz]); pos[a] = sz; sz++; } } void erase(int a) { if (pos[a] < sz) { sz--; pos[list[sz]] = pos[a]; swap(list[pos[a]], list[sz]); pos[a] = sz; } } inline int size() { return sz; } inline int rand() { return list[rnd.nextInt(sz)]; } inline void erase_all() { sz = 0; } }; const int DX[4] = {1, 0, -1, 0}; const int DY[4] = {0, 1, 0, -1}; const int REV[4] = {2, 3, 0, 1}; const string DIR = "DRUL"; int N2M; // Number of empty cells int M; int B[N][N]; int neighbor[N2MMAX][4]; int empty_to_original_X[N2MMAX]; int empty_to_original_Y[N2MMAX]; int to_converted_index[N2]; short initial_ice_board[4][N2MMAX]; double initial_probability[N2MMAX]; short get_initial_ice_board(int k, int i) { if (initial_ice_board[k][i] == -1) { if (neighbor[i][k] == -1) { initial_ice_board[k][i] = i; } else { initial_ice_board[k][i] = get_initial_ice_board(k, neighbor[i][k]); } } return initial_ice_board[k][i]; } void calc_next_probability(double cur[N2MMAX], double ne[N2MMAX], short initial_ice_board[4][N2MMAX], FastSet2& empty_cells) { for (int i = 0; i < empty_cells.size(); i++) { int idx = empty_cells.list[i]; ne[idx] = 0; } for (int i = 0; i < empty_cells.size(); i++) { int idx = empty_cells.list[i]; for (int k = 0; k < 4; k++) { int next_idx = initial_ice_board[k][idx]; ne[next_idx] += cur[idx] / 4.0; } } } void init() { for (int i = 0; i < N2; i++) { int x = i / N; int y = i % N; if (B[x][y] == 0) { for (int k = 0; k < 4; k++) { int nx = x + DX[k]; int ny = y + DY[k]; if (nx >= 0 && nx < N && ny >= 0 && ny < N && B[nx][ny] == 0) { neighbor[to_converted_index[i]][k] = to_converted_index[nx * N + ny]; } else { neighbor[to_converted_index[i]][k] = -1; } } } } for (int i = 0; i < N2M; i++) { for (int k = 0; k < 4; k++) { initial_ice_board[k][i] = -1; } } for (int i = 0; i < N2M; i++) { for (int k = 0; k < 4; k++) { get_initial_ice_board(k, i); } } double uniform_probability[N2MMAX]; for (int i = 0; i < N2M; i++) { uniform_probability[i] = 1.0 / N2M; } FastSet2 empty_cells; empty_cells.init(N2M); empty_cells.insert_all(); calc_next_probability(uniform_probability, initial_probability, initial_ice_board, empty_cells); } void put_stone(int idx, FastSet2& empty_cells, double cur[N2MMAX], double ne[N2MMAX], short ice_board[4][N2MMAX]) { empty_cells.erase(idx); if (empty_cells.size() == 0) { return; } // update ice board for (int k = 0; k < 4; k++) { if (neighbor[idx][k] == -1 || empty_cells.pos[neighbor[idx][k]] >= empty_cells.size()) { continue; } int reach_idx = neighbor[idx][k]; int n_idx = reach_idx; ice_board[REV[k]][n_idx] = reach_idx; while (neighbor[n_idx][k] != -1 && empty_cells.pos[neighbor[n_idx][k]] < empty_cells.size()) { n_idx = neighbor[n_idx][k]; ice_board[REV[k]][n_idx] = reach_idx; } } // update probability calc_next_probability(cur, ne, ice_board, empty_cells); } void put_stone_only(int idx, FastSet2& empty_cells, short ice_board[4][N2MMAX]) { empty_cells.erase(idx); if (empty_cells.size() == 0) { return; } // update ice board for (int k = 0; k < 4; k++) { if (neighbor[idx][k] == -1 || empty_cells.pos[neighbor[idx][k]] >= empty_cells.size()) { continue; } int reach_idx = neighbor[idx][k]; int n_idx = reach_idx; ice_board[REV[k]][n_idx] = reach_idx; while (neighbor[n_idx][k] != -1 && empty_cells.pos[neighbor[n_idx][k]] < empty_cells.size()) { n_idx = neighbor[n_idx][k]; ice_board[REV[k]][n_idx] = reach_idx; } } } struct Params { int phase1; double weight; Params(int _phase1, double _weight) : phase1(_phase1), weight(_weight) {} }; double solve_greedy(FastSet2& empty_cells, int order[], Params& params) { empty_cells.insert_all(); double cur[N2MMAX]; double ne[N2MMAX]; for (int i = 0; i < N2M; i++) { cur[i] = initial_probability[i]; ne[i] = 0; } short ice_board[4][N2MMAX]; for (int k = 0; k < 4; k++) { for (int i = 0; i < N2M; i++) { ice_board[k][i] = initial_ice_board[k][i]; } } double score = 0; double accumulated_probability = 0; for (int i = 0; i < N2M; i++) { int best_idx = -1; double best_eval = -1e9; for (int _j = 0; _j < empty_cells.size(); _j++) { int idx = empty_cells.list[_j]; double eval = -1e4 * cur[idx]; if (i > 0) { for (int k = 0; k < 4; k++) { if (i < params.phase1) { if (neighbor[idx][k] == -1 || empty_cells.pos[neighbor[idx][k]] >= empty_cells.size()) { continue; } if (ne[neighbor[idx][k]] > cur[neighbor[idx][k]]) { eval += 1 * cur[neighbor[idx][k]]; } else { eval += params.weight * cur[neighbor[idx][k]]; } } else { eval -= cur[ice_board[k][idx]]; if (neighbor[idx][k] == -1 || empty_cells.pos[neighbor[idx][k]] >= empty_cells.size()) { continue; } if (ne[neighbor[idx][k]] > cur[neighbor[idx][k]]) { eval += 1e-5 * cur[neighbor[idx][k]]; } else { eval += 1e-5 * cur[neighbor[idx][k]]; } } } } if (eval > best_eval) { best_eval = eval; best_idx = idx; } } order[i] = best_idx; accumulated_probability += cur[best_idx]; score += accumulated_probability; put_stone(best_idx, empty_cells, cur, ne, ice_board); swap(cur, ne); } return score; } void solve() { // vector<int> start_order = solve_cycle(); FastSet2 empty_cells; empty_cells.init(N2M); double best_score = 1e9; Params params(30, 10.0); Params best_params(30, 10.0); int best_order[N2M]; int cnt = 0; while (true) { cnt++; double ti = timer.get(); if (ti > TIMELIMIT) { break; } int order[N2M]; double rand_weight = rnd.nextDouble(); if (rand_weight < 0.5) { params.phase1 += rnd.nextInt(7) - 3; } else { params.weight += rnd.nextDouble() * 2 - 1; } double score = solve_greedy(empty_cells, order, params); if (score < best_score) { best_score = score; best_params = params; for (int i = 0; i < N2M; i++) { best_order[i] = order[i]; } cerr << "best_score = " << best_score << endl; cerr << "params = " << params.phase1 << " " << params.weight << endl; }else{ params = best_params; } } cerr << "cnt = " << cnt << endl; cerr << "score = " << 1e6 * (N2M - best_score) / (N2M - 1) << endl; for (int i = 0; i < N2M; i++) { int x = empty_to_original_X[best_order[i]]; int y = empty_to_original_Y[best_order[i]]; cout << x << " " << y << endl; } } void input() { int _; int _M; cin >> _ >> _M; string s; M = 0; for (int i = 0; i < N; i++) { cin >> s; for (int j = 0; j < N; j++) { if (s[j] == '#') { B[i][j] = 1; } else { B[i][j] = 0; empty_to_original_X[M] = i; empty_to_original_Y[M] = j; to_converted_index[i * N + j] = M; M++; } } } M = N2 - M; assert(M == _M); N2M = N2 - M; } int main(int argc, char* argv[]) { input(); init(); solve(); cerr << "timer = " << timer.get() << endl; return 0; }
Submission Info
Submission Time | |
---|---|
Task | A - Gamble on Ice |
User | ats5515 |
Language | C++ 20 (gcc 12.2) |
Score | 149031842 |
Code Size | 9423 Byte |
Status | AC |
Exec Time | 1963 ms |
Memory | 4708 KiB |
Compile Error
Main.cpp: In function ‘int main(int, char**)’: Main.cpp:393:14: warning: unused parameter ‘argc’ [-Wunused-parameter] 393 | int main(int argc, char* argv[]) { | ~~~~^~~~ Main.cpp:393:26: warning: unused parameter ‘argv’ [-Wunused-parameter] 393 | int main(int argc, char* argv[]) { | ~~~~~~^~~~~~
Judge Result
Set Name | test_ALL | ||
---|---|---|---|
Score / Max Score | 149031842 / 150000000 | ||
Status |
|
Set Name | Test Cases |
---|---|
test_ALL | test_0000.txt, test_0001.txt, test_0002.txt, test_0003.txt, test_0004.txt, test_0005.txt, test_0006.txt, test_0007.txt, test_0008.txt, test_0009.txt, test_0010.txt, test_0011.txt, test_0012.txt, test_0013.txt, test_0014.txt, test_0015.txt, test_0016.txt, test_0017.txt, test_0018.txt, test_0019.txt, test_0020.txt, test_0021.txt, test_0022.txt, test_0023.txt, test_0024.txt, test_0025.txt, test_0026.txt, test_0027.txt, test_0028.txt, test_0029.txt, test_0030.txt, test_0031.txt, test_0032.txt, test_0033.txt, test_0034.txt, test_0035.txt, test_0036.txt, test_0037.txt, test_0038.txt, test_0039.txt, test_0040.txt, test_0041.txt, test_0042.txt, test_0043.txt, test_0044.txt, test_0045.txt, test_0046.txt, test_0047.txt, test_0048.txt, test_0049.txt, test_0050.txt, test_0051.txt, test_0052.txt, test_0053.txt, test_0054.txt, test_0055.txt, test_0056.txt, test_0057.txt, test_0058.txt, test_0059.txt, test_0060.txt, test_0061.txt, test_0062.txt, test_0063.txt, test_0064.txt, test_0065.txt, test_0066.txt, test_0067.txt, test_0068.txt, test_0069.txt, test_0070.txt, test_0071.txt, test_0072.txt, test_0073.txt, test_0074.txt, test_0075.txt, test_0076.txt, test_0077.txt, test_0078.txt, test_0079.txt, test_0080.txt, test_0081.txt, test_0082.txt, test_0083.txt, test_0084.txt, test_0085.txt, test_0086.txt, test_0087.txt, test_0088.txt, test_0089.txt, test_0090.txt, test_0091.txt, test_0092.txt, test_0093.txt, test_0094.txt, test_0095.txt, test_0096.txt, test_0097.txt, test_0098.txt, test_0099.txt, test_0100.txt, test_0101.txt, test_0102.txt, test_0103.txt, test_0104.txt, test_0105.txt, test_0106.txt, test_0107.txt, test_0108.txt, test_0109.txt, test_0110.txt, test_0111.txt, test_0112.txt, test_0113.txt, test_0114.txt, test_0115.txt, test_0116.txt, test_0117.txt, test_0118.txt, test_0119.txt, test_0120.txt, test_0121.txt, test_0122.txt, test_0123.txt, test_0124.txt, test_0125.txt, test_0126.txt, test_0127.txt, test_0128.txt, test_0129.txt, test_0130.txt, test_0131.txt, test_0132.txt, test_0133.txt, test_0134.txt, test_0135.txt, test_0136.txt, test_0137.txt, test_0138.txt, test_0139.txt, test_0140.txt, test_0141.txt, test_0142.txt, test_0143.txt, test_0144.txt, test_0145.txt, test_0146.txt, test_0147.txt, test_0148.txt, test_0149.txt |
Case Name | Status | Exec Time | Memory |
---|---|---|---|
test_0000.txt | AC | 1963 ms | 4640 KiB |
test_0001.txt | AC | 1956 ms | 4704 KiB |
test_0002.txt | AC | 1960 ms | 4656 KiB |
test_0003.txt | AC | 1954 ms | 4632 KiB |
test_0004.txt | AC | 1956 ms | 4496 KiB |
test_0005.txt | AC | 1957 ms | 4496 KiB |
test_0006.txt | AC | 1957 ms | 4568 KiB |
test_0007.txt | AC | 1954 ms | 4596 KiB |
test_0008.txt | AC | 1958 ms | 4544 KiB |
test_0009.txt | AC | 1957 ms | 4632 KiB |
test_0010.txt | AC | 1960 ms | 4536 KiB |
test_0011.txt | AC | 1953 ms | 4704 KiB |
test_0012.txt | AC | 1954 ms | 4660 KiB |
test_0013.txt | AC | 1958 ms | 4544 KiB |
test_0014.txt | AC | 1957 ms | 4660 KiB |
test_0015.txt | AC | 1955 ms | 4504 KiB |
test_0016.txt | AC | 1961 ms | 4648 KiB |
test_0017.txt | AC | 1954 ms | 4628 KiB |
test_0018.txt | AC | 1957 ms | 4636 KiB |
test_0019.txt | AC | 1957 ms | 4664 KiB |
test_0020.txt | AC | 1956 ms | 4652 KiB |
test_0021.txt | AC | 1957 ms | 4632 KiB |
test_0022.txt | AC | 1958 ms | 4636 KiB |
test_0023.txt | AC | 1957 ms | 4660 KiB |
test_0024.txt | AC | 1952 ms | 4700 KiB |
test_0025.txt | AC | 1960 ms | 4536 KiB |
test_0026.txt | AC | 1959 ms | 4640 KiB |
test_0027.txt | AC | 1957 ms | 4500 KiB |
test_0028.txt | AC | 1954 ms | 4636 KiB |
test_0029.txt | AC | 1959 ms | 4648 KiB |
test_0030.txt | AC | 1959 ms | 4600 KiB |
test_0031.txt | AC | 1956 ms | 4544 KiB |
test_0032.txt | AC | 1955 ms | 4632 KiB |
test_0033.txt | AC | 1954 ms | 4540 KiB |
test_0034.txt | AC | 1960 ms | 4632 KiB |
test_0035.txt | AC | 1955 ms | 4700 KiB |
test_0036.txt | AC | 1959 ms | 4564 KiB |
test_0037.txt | AC | 1960 ms | 4560 KiB |
test_0038.txt | AC | 1953 ms | 4704 KiB |
test_0039.txt | AC | 1957 ms | 4660 KiB |
test_0040.txt | AC | 1954 ms | 4500 KiB |
test_0041.txt | AC | 1958 ms | 4632 KiB |
test_0042.txt | AC | 1958 ms | 4652 KiB |
test_0043.txt | AC | 1958 ms | 4636 KiB |
test_0044.txt | AC | 1955 ms | 4568 KiB |
test_0045.txt | AC | 1958 ms | 4700 KiB |
test_0046.txt | AC | 1961 ms | 4700 KiB |
test_0047.txt | AC | 1956 ms | 4500 KiB |
test_0048.txt | AC | 1959 ms | 4664 KiB |
test_0049.txt | AC | 1961 ms | 4584 KiB |
test_0050.txt | AC | 1959 ms | 4564 KiB |
test_0051.txt | AC | 1955 ms | 4648 KiB |
test_0052.txt | AC | 1953 ms | 4708 KiB |
test_0053.txt | AC | 1959 ms | 4632 KiB |
test_0054.txt | AC | 1961 ms | 4704 KiB |
test_0055.txt | AC | 1957 ms | 4636 KiB |
test_0056.txt | AC | 1956 ms | 4504 KiB |
test_0057.txt | AC | 1953 ms | 4500 KiB |
test_0058.txt | AC | 1958 ms | 4504 KiB |
test_0059.txt | AC | 1958 ms | 4496 KiB |
test_0060.txt | AC | 1959 ms | 4492 KiB |
test_0061.txt | AC | 1959 ms | 4552 KiB |
test_0062.txt | AC | 1957 ms | 4660 KiB |
test_0063.txt | AC | 1958 ms | 4600 KiB |
test_0064.txt | AC | 1958 ms | 4636 KiB |
test_0065.txt | AC | 1955 ms | 4496 KiB |
test_0066.txt | AC | 1953 ms | 4640 KiB |
test_0067.txt | AC | 1960 ms | 4636 KiB |
test_0068.txt | AC | 1959 ms | 4600 KiB |
test_0069.txt | AC | 1955 ms | 4632 KiB |
test_0070.txt | AC | 1956 ms | 4640 KiB |
test_0071.txt | AC | 1954 ms | 4632 KiB |
test_0072.txt | AC | 1957 ms | 4636 KiB |
test_0073.txt | AC | 1953 ms | 4656 KiB |
test_0074.txt | AC | 1961 ms | 4664 KiB |
test_0075.txt | AC | 1959 ms | 4640 KiB |
test_0076.txt | AC | 1955 ms | 4704 KiB |
test_0077.txt | AC | 1954 ms | 4660 KiB |
test_0078.txt | AC | 1955 ms | 4628 KiB |
test_0079.txt | AC | 1961 ms | 4628 KiB |
test_0080.txt | AC | 1957 ms | 4636 KiB |
test_0081.txt | AC | 1960 ms | 4664 KiB |
test_0082.txt | AC | 1954 ms | 4548 KiB |
test_0083.txt | AC | 1955 ms | 4636 KiB |
test_0084.txt | AC | 1954 ms | 4500 KiB |
test_0085.txt | AC | 1959 ms | 4644 KiB |
test_0086.txt | AC | 1957 ms | 4552 KiB |
test_0087.txt | AC | 1957 ms | 4628 KiB |
test_0088.txt | AC | 1953 ms | 4656 KiB |
test_0089.txt | AC | 1959 ms | 4700 KiB |
test_0090.txt | AC | 1960 ms | 4632 KiB |
test_0091.txt | AC | 1954 ms | 4636 KiB |
test_0092.txt | AC | 1961 ms | 4656 KiB |
test_0093.txt | AC | 1956 ms | 4556 KiB |
test_0094.txt | AC | 1954 ms | 4648 KiB |
test_0095.txt | AC | 1957 ms | 4636 KiB |
test_0096.txt | AC | 1956 ms | 4632 KiB |
test_0097.txt | AC | 1954 ms | 4640 KiB |
test_0098.txt | AC | 1960 ms | 4500 KiB |
test_0099.txt | AC | 1958 ms | 4636 KiB |
test_0100.txt | AC | 1954 ms | 4632 KiB |
test_0101.txt | AC | 1956 ms | 4556 KiB |
test_0102.txt | AC | 1956 ms | 4640 KiB |
test_0103.txt | AC | 1958 ms | 4640 KiB |
test_0104.txt | AC | 1955 ms | 4656 KiB |
test_0105.txt | AC | 1959 ms | 4500 KiB |
test_0106.txt | AC | 1957 ms | 4500 KiB |
test_0107.txt | AC | 1956 ms | 4640 KiB |
test_0108.txt | AC | 1962 ms | 4600 KiB |
test_0109.txt | AC | 1955 ms | 4600 KiB |
test_0110.txt | AC | 1956 ms | 4632 KiB |
test_0111.txt | AC | 1959 ms | 4640 KiB |
test_0112.txt | AC | 1956 ms | 4656 KiB |
test_0113.txt | AC | 1961 ms | 4596 KiB |
test_0114.txt | AC | 1954 ms | 4632 KiB |
test_0115.txt | AC | 1956 ms | 4636 KiB |
test_0116.txt | AC | 1961 ms | 4636 KiB |
test_0117.txt | AC | 1955 ms | 4704 KiB |
test_0118.txt | AC | 1961 ms | 4500 KiB |
test_0119.txt | AC | 1959 ms | 4636 KiB |
test_0120.txt | AC | 1953 ms | 4556 KiB |
test_0121.txt | AC | 1958 ms | 4636 KiB |
test_0122.txt | AC | 1953 ms | 4540 KiB |
test_0123.txt | AC | 1955 ms | 4500 KiB |
test_0124.txt | AC | 1959 ms | 4632 KiB |
test_0125.txt | AC | 1957 ms | 4632 KiB |
test_0126.txt | AC | 1953 ms | 4552 KiB |
test_0127.txt | AC | 1958 ms | 4568 KiB |
test_0128.txt | AC | 1955 ms | 4640 KiB |
test_0129.txt | AC | 1960 ms | 4628 KiB |
test_0130.txt | AC | 1957 ms | 4636 KiB |
test_0131.txt | AC | 1955 ms | 4500 KiB |
test_0132.txt | AC | 1956 ms | 4636 KiB |
test_0133.txt | AC | 1957 ms | 4504 KiB |
test_0134.txt | AC | 1955 ms | 4636 KiB |
test_0135.txt | AC | 1955 ms | 4540 KiB |
test_0136.txt | AC | 1959 ms | 4568 KiB |
test_0137.txt | AC | 1954 ms | 4600 KiB |
test_0138.txt | AC | 1958 ms | 4640 KiB |
test_0139.txt | AC | 1961 ms | 4500 KiB |
test_0140.txt | AC | 1956 ms | 4564 KiB |
test_0141.txt | AC | 1953 ms | 4552 KiB |
test_0142.txt | AC | 1954 ms | 4640 KiB |
test_0143.txt | AC | 1961 ms | 4656 KiB |
test_0144.txt | AC | 1961 ms | 4536 KiB |
test_0145.txt | AC | 1963 ms | 4636 KiB |
test_0146.txt | AC | 1954 ms | 4660 KiB |
test_0147.txt | AC | 1954 ms | 4636 KiB |
test_0148.txt | AC | 1960 ms | 4536 KiB |
test_0149.txt | AC | 1961 ms | 4556 KiB |