#include using namespace std; #define ll long long #define INF 9223372036854775800LL #define MOD 1000000007 int mat[200][200]; int q[201][201]; int q_score[200][200]; int n,r,k; int collisions = 0; int score = 0; int best_score = 0; double rank_dp[200][200]; int largest_cell = 0; //double max_rank = 0; //double min_rank = 20000000000; set > > curr; set > > best; //map , set< pair > > colliding_queens; set > colliding_queens[200][200]; set > empty_set; double get_rank(int x, int y){ if(!isnan(rank_dp[x][y])) return rank_dp[x][y]; double col_score = (double)colliding_queens[x][y].size(); double score_ratio = ((double)q_score[x][y]); double rank_ = score_ratio/(col_score);//score_ratio/col_score; // max_rank = max(max_rank, rank_); //min_rank = min(min_rank, rank_); return rank_dp[x][y] = rank_; //(col_score*col_score);//* (col_score+0.1); } void invalidate_rank(int x, int y){ rank_dp[x][y] = NAN; } int ck_count = 0; void check_collision(pair &origpair, pair &currpair){ ck_count++; if(q[currpair.first][currpair.second]){ double old_rank = get_rank(currpair.first, currpair.second); colliding_queens[origpair.first][origpair.second].insert(currpair); colliding_queens[currpair.first][currpair.second].insert(origpair); invalidate_rank(currpair.first,currpair.second); double new_rank = get_rank(currpair.first,currpair.second); curr.erase(make_pair(old_rank, currpair )); curr.insert(make_pair(new_rank, currpair )); } } int calc_score(int x, int y){ if(q_score[x][y] > 0) return q_score[x][y]; pair xypair = make_pair(x,y); int left = max(0, y-r); int right = min(n-1, y+r); int top = max(0, x-r); int bot = min(n-1, x+r); int visited[51] = {0}; pair curr_pair = make_pair(x,0); for(int i=left; i<=right; ++i){ visited[mat[x][i]]++; curr_pair.second = i; } curr_pair.second = y; for(int i=top; i<=bot; ++i){ curr_pair.first = i; visited[mat[i][y] ]++; } // left up curr_pair.first = x; curr_pair.second = y; while(curr_pair.first>=0 && curr_pair.second>=0){ visited[ mat[curr_pair.first][curr_pair.second] ]++; curr_pair.first--; curr_pair.second--; } // right up curr_pair.first = x; curr_pair.second = y; while(curr_pair.first>=0 && curr_pair.second=0){ visited[ mat[curr_pair.first][curr_pair.second] ]++; curr_pair.first++; curr_pair.second--; } // right down curr_pair.first = x+1; curr_pair.second = y+1; while(curr_pair.first xypair = make_pair(x,y); int left = max(0, y-r); int right = min(n-1, y+r); int top = max(0, x-r); int bot = min(n-1, x+r); pair curr_pair = make_pair(x,0); for(int i=left; i<=right; ++i){ curr_pair.second = i; check_collision(xypair, curr_pair); } curr_pair.second = y; for(int i=top; i<=bot; ++i){ curr_pair.first = i; check_collision(xypair, curr_pair); } // left up curr_pair.first = x; curr_pair.second = y; while(curr_pair.first>=0 && curr_pair.second>=0){ check_collision(xypair, curr_pair); curr_pair.first--; curr_pair.second--; } // right up curr_pair.first = x; curr_pair.second = y; while(curr_pair.first>=0 && curr_pair.second=0){ check_collision(xypair, curr_pair); curr_pair.first++; curr_pair.second--; } // right down curr_pair.first = x+1; curr_pair.second = y+1; while(curr_pair.first > curr_coll = colliding_queens[x][y]; double rank_ = get_rank(x, y); curr.erase(make_pair(rank_, make_pair(x, y)) ); q[x][y] = 0; score-= q_score[x][y]; collisions-= curr_coll.size(); //q_score[x][y] = 0; for(auto it = curr_coll.begin(); it!=curr_coll.end(); ++it){ colliding_queens[(*it).first][(*it).second].erase(make_pair(x,y)); } colliding_queens[x][y] = empty_set; rank_dp[x][y] = NAN; } int main() { vector > > cells; ios_base::sync_with_stdio(false); cin.tie(0); memset(q, 0, sizeof(q)); memset(q_score, 0, sizeof(q_score)); time_t start = time(0); srand((unsigned)time(0)); #ifdef DEBUG freopen("C:\\in.txt", "r", stdin); #else freopen("queens.in", "r", stdin); freopen("queens.out", "w", stdout); #endif cin >> n >> r >> k; for(int i=0; i> mat[i][j]; rank_dp[i][j] = NAN; } } for(int i=0; i=cells.size()){ new_x = rand()%n; new_y = rand()%n; } else { new_x = cells[ind].second.first; new_y = cells[ind].second.second; ind++; } if(!q[new_x][new_y]){ add(new_x, new_y); } while(difftime( time(0), start) < end_time && collisions > k){ random = true; pair to_be_removed; auto it = curr.begin(); to_be_removed = (*it).second; remove_q(to_be_removed.first, to_be_removed.second); } if(collisions <= k && score > best_score){ best = curr; best_score = score; } } for(auto it = best.begin(); it!=best.end(); ++it){ cout << (*it).second.first+1 << " " << (*it).second.second+1 << '\n'; } #ifdef DEBUG cout << best_score << " from " << iterations << " iterations"<< '\n'; #endif return 0; }