#include #include #include #include #include #include namespace Solver { using namespace std; int N_val, M_val; vector> edges; bool adj[45][45]; vector adj_list[45]; struct State { int K; vector> grid; int color_counts[45]; int edge_counts[45][45]; int realized_edge_count; int present_color_count; void init(int k, int n) { K = k; grid.assign(K, vector(K, 1)); for(int i=0; i<=n; ++i) color_counts[i] = 0; for(int i=0; i<=n; ++i) for(int j=0; j<=n; ++j) edge_counts[i][j] = 0; realized_edge_count = 0; present_color_count = 0; // Initial grid is all 1s color_counts[1] = K * K; present_color_count = 1; } bool is_valid_change(int r, int c, int new_color) { int dr[] = {-1, 1, 0, 0}; int dc[] = {0, 0, -1, 1}; for(int i=0; i<4; ++i) { int nr = r + dr[i]; int nc = c + dc[i]; if(nr >= 0 && nr < K && nc >= 0 && nc < K) { int neighbor_color = grid[nr][nc]; if(neighbor_color != new_color) { if(!adj[new_color][neighbor_color]) return false; } } } return true; } void apply_change(int r, int c, int new_color) { int old_color = grid[r][c]; if(old_color == new_color) return; int dr[] = {-1, 1, 0, 0}; int dc[] = {0, 0, -1, 1}; // Remove old adjacencies for(int i=0; i<4; ++i) { int nr = r + dr[i]; int nc = c + dc[i]; if(nr >= 0 && nr < K && nc >= 0 && nc < K) { int neighbor = grid[nr][nc]; if(neighbor != old_color) { int u = min(old_color, neighbor); int v = max(old_color, neighbor); if(adj[u][v]) { edge_counts[u][v]--; if(edge_counts[u][v] == 0) realized_edge_count--; } } } } color_counts[old_color]--; if(color_counts[old_color] == 0) present_color_count--; grid[r][c] = new_color; color_counts[new_color]++; if(color_counts[new_color] == 1) present_color_count++; // Add new adjacencies for(int i=0; i<4; ++i) { int nr = r + dr[i]; int nc = c + dc[i]; if(nr >= 0 && nr < K && nc >= 0 && nc < K) { int neighbor = grid[nr][nc]; if(neighbor != new_color) { int u = min(new_color, neighbor); int v = max(new_color, neighbor); if(adj[u][v]) { if(edge_counts[u][v] == 0) realized_edge_count++; edge_counts[u][v]++; } } } } } }; vector> solve_for_K(int N, int M, int K, double time_limit_sec) { State state; state.init(K, N); clock_t start_time = clock(); int max_iter = 10000000; for(int iter=0; iter time_limit_sec) return {}; if(state.present_color_count == N && state.realized_edge_count == M) { return state.grid; } } bool missing_color = (state.present_color_count < N); if (missing_color) { int target = -1; vector missing; for(int c=1; c<=N; ++c) if(state.color_counts[c] == 0) missing.push_back(c); if(!missing.empty()) target = missing[rand() % missing.size()]; if(target != -1) { bool found_friend = false; for(int neighbor : adj_list[target]) { if(state.color_counts[neighbor] > 0) { found_friend = true; break; } } bool moved = false; int attempts = 50; while(attempts--) { int r = rand() % K; int c = rand() % K; if(state.is_valid_change(r, c, target)) { bool connects = false; if(found_friend) { int dr[] = {-1, 1, 0, 0}; int dc[] = {0, 0, -1, 1}; for(int d=0; d<4; ++d) { int nr = r + dr[d], nc = c + dc[d]; if(nr>=0 && nr=0 && nc> missing_edges; for(auto& e : edges) { if(state.edge_counts[e.first][e.second] == 0) { missing_edges.push_back(e); } } if(!missing_edges.empty()) { auto target_edge = missing_edges[rand() % missing_edges.size()]; int u = target_edge.first; int v = target_edge.second; bool u_exists = state.color_counts[u] > 0; bool v_exists = state.color_counts[v] > 0; if(u_exists && v_exists) { bool success = false; int tries = 50; while(tries--) { int r = rand() % K; int c = rand() % K; int current = state.grid[r][c]; if(current == u) { int dr[] = {-1, 1, 0, 0}; int dc[] = {0, 0, -1, 1}; int d = rand() % 4; int nr = r + dr[d], nc = c + dc[d]; if(nr>=0 && nr=0 && nc=0 && nr=0 && nc valid_colors; valid_colors.reserve(N); for(int clr=1; clr<=N; ++clr) { if(state.is_valid_change(r, c, clr)) { valid_colors.push_back(clr); } } if(!valid_colors.empty()) { int best_c = -1; int best_gain = -10000; if(valid_colors.size() > 5) { for(int i=0; i<5; ++i) { swap(valid_colors[i], valid_colors[i + rand()%(valid_colors.size()-i)]); } valid_colors.resize(5); } for(int clr : valid_colors) { if(clr == state.grid[r][c]) continue; int gain = 0; if(state.color_counts[clr] == 0) gain += 1000; if(state.color_counts[state.grid[r][c]] == 1) gain -= 1000; int dr[] = {-1, 1, 0, 0}; int dc[] = {0, 0, -1, 1}; for(int i=0; i<4; ++i) { int nr = r + dr[i], nc = c + dc[i]; if(nr>=0 && nr=0 && nc=0 && nr=0 && nc best_gain) { best_gain = gain; best_c = clr; } } if(best_c != -1) { if(best_gain >= 0 || (rand() % 20 == 0)) state.apply_change(r, c, best_c); } } } return {}; } } std::vector> create_map(int N, int M, std::vector A, std::vector B) { using namespace Solver; N_val = N; M_val = M; for(int i=0; i<=N; ++i) { adj_list[i].clear(); for(int j=0; j<=N; ++j) adj[i][j] = false; } edges.clear(); for(int i=0; i= N) K1 = 0; if(K1 > 0) { vector> res = solve_for_K(N, M, K1, 0.5); if(!res.empty()) return res; } int K2 = max(K1 + 1, (int)(N * 0.75)); if(K2 >= N) K2 = 0; if(K2 > 0) { vector> res = solve_for_K(N, M, K2, 0.5); if(!res.empty()) return res; } vector> res = solve_for_K(N, M, min(N, 240), 1.9); if(!res.empty()) return res; vector> dummy(N, vector(N, 1)); for(int i=0; i