#include #include #include #include using namespace std; using i32 = int32_t; using u32 = uint32_t; using i64 = int64_t; using u64 = uint64_t; #define rep(i,n) for(int i=0; i<(n); i++) vector player_skills; vector player_times; struct Room{ int id; vector players; int value_e; Room(int player_id){ id = player_id; players = { id }; value_e = 0; } int get_num_players() const { return players.size(); } pair merge_in(Room another, int tick){ value_e += another.value_e; for(int l : players) for(int r : another.players){ value_e += tick - player_times[l]; value_e += tick - player_times[r]; } for(int r : another.players) players.push_back(r); return { id, another.id }; } double receive_score(int player_id, int tick){ double skill = player_skills[player_id]; int min_skill = 100; int max_skill = 0; int min_tick = 1001001; for(auto a : players){ min_skill = min(min_skill, player_skills[a]); max_skill = max(max_skill, player_skills[a]); min_tick = min(min_tick, player_times[a]); } if(min_skill <= skill && skill <= max_skill) return 1.0e100; double mid_skill = (min_skill + max_skill) / 2.0; tick -= min_tick; double w = pow((mid_skill - 50.0) / 50.0, 2.0) * 2.0 + 3.0; //double w = 4.0; double margin_ticks = 30.0; double margin_w = 0.0; if(tick >= margin_ticks) w += (log(tick / margin_ticks)) * 1.0; // if(tick >= margin_ticks) margin_w += (tick - margin_ticks) / 20; // if(tick >= margin_ticks) cerr << margin_w << endl; w += margin_w; double l = min(min_skill, max_skill - w); double r = max(max_skill, min_skill + w); auto skill_dist = abs(mid_skill - skill) / 100.0; return (l <= skill && skill <= r) ? (100.0 - skill_dist) : 0.0; } }; int main(){ vector rooms; int num_tick; cin >> num_tick; int max_room_size; cin >> max_room_size; int next_player_id = 1; player_skills.push_back(0); player_times.push_back(0); rep(tick_idx, num_tick){ int num_enter; cin >> num_enter; vector> buf; rep(enter_idx, num_enter){ int enter_id = next_player_id++; int player_skill; cin >> player_skill; player_skills.push_back(player_skill); player_times.push_back(tick_idx); int to_enter = -1; double receive_score_max = 0.0; rep(room_arr_idx, rooms.size()){ auto receive_score = rooms[room_arr_idx].receive_score(enter_id, tick_idx); if(receive_score > receive_score_max){ to_enter = room_arr_idx; receive_score_max = receive_score; } } if(to_enter == -1){ rooms.emplace_back(enter_id); } else{ buf.push_back(rooms[to_enter].merge_in(Room(enter_id), tick_idx)); if(rooms[to_enter].players.size() >= max_room_size){ swap(rooms[to_enter], rooms.back()); rooms.pop_back(); } } } cout << buf.size() << "\n"; for(auto a : buf){ cout << a.first << " " << a.second << "\n"; } cout << flush; } return 0; } struct ios_do_not_sync { ios_do_not_sync() { ios::sync_with_stdio(false); cin.tie(nullptr); } } ios_do_not_sync_instance;