一生一代一双人,争教两处销魂。相思相望不相亲,天为谁春?
浆向蓝桥易乞,药成碧海难奔。若容相访饮牛津,相对忘贫。
题目描述
洛谷链接: https://www.luogu.com.cn/problem/U214788
有n n n 个巨人和n n n 个鬼正在战斗。每个巨人都配备了质子炮,可以发射质子流来消灭鬼。质子流沿直线行进,击中鬼之后就会消失。
由于质子流威力巨大,一旦两束质子流发生碰撞,后果不堪设想。因此,巨人必须谨慎地选择鬼作为射击目标,以便保证质子流不会发生碰撞。
已知巨人和鬼的坐标没有三者是共线的,求可行的射击方案。
输入
第一行一个正整数n n n ,表示巨人和鬼的个数。
接下来n n n 行,每行三个数,第一个数表示该巨人的i d id i d ,后两个是浮点数,分别表示该巨人的x x x 坐标和y y y 坐标。
接下来n n n 行,每行三个数,分别表示鬼的i d id i d ,鬼的x x x 坐标和y y y 坐标。
输出
输出n n n 行,每行两个整数g i a n t i giant_i g ian t i , g h o s t i ghost_i g h os t i ,表示i d id i d 为g i a n t i giant_i g ian t i 的巨人的射击目标是i d id i d 为g h o s t i ghost_i g h os t i 的鬼。
样例
输入
2
0 0.00 0.00
1 1.00 0.00
0 0.00 1.00
1 2.00 2.00
输出
0 0
1 1
数据范围
n ≤ 2100
n \leq 2100
n ≤ 2100
具体实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 #include <vector> #include <iostream> #include <algorithm> #include <cassert> using std::pair;using std::vector;struct giant_ghost { double x; double y; bool is_giant; int id; }; vector<giant_ghost> giants_ghosts; vector<pair<int , int >> ans; void giants_and_ghosts (int l, int r) { if (l > r) return ; assert ((r - l) % 2 != 0 ); if (r - l == 1 ) { assert (giants_ghosts[l].is_giant || giants_ghosts[r].is_giant); assert (!(giants_ghosts[l].is_giant && giants_ghosts[r].is_giant)); if (giants_ghosts[l].is_giant) { ans.push_back (std::make_pair (giants_ghosts[l].id, giants_ghosts[r].id)); } else { ans.push_back (std::make_pair (giants_ghosts[r].id, giants_ghosts[l].id)); } return ; } int index = l; giant_ghost left = giants_ghosts[l]; for (int i = l + 1 ; i <= r; i++) { if (giants_ghosts[i].y < left.y || giants_ghosts[i].y == left.y && giants_ghosts[i].x < left.x) { index = i; left = giants_ghosts[i]; } } left = giants_ghosts[l]; giants_ghosts[l] = giants_ghosts[index]; giants_ghosts[index] = left; left = giants_ghosts[l]; std::sort (giants_ghosts.begin () + 1 + l, giants_ghosts.begin () + 1 + r, [&left](const giant_ghost &g1, const giant_ghost &g2) { double x1 = g1.x - left.x; double y1 = g1.y - left.y; double x2 = g2.x - left.x; double y2 = g2.y - left.y; return x1 * y2 - x2 * y1 > 0 ; }); int giant_cnt = left.is_giant ? 1 : 0 ; int ghost_cnt = left.is_giant ? 0 : 1 ; index = l; do { index++; assert (index <= r); if (giants_ghosts[index].is_giant) giant_cnt++; else ghost_cnt++; } while (giant_cnt != ghost_cnt); if (giants_ghosts[l].is_giant) ans.push_back (std::make_pair (giants_ghosts[l].id, giants_ghosts[index].id)); else ans.push_back (std::make_pair (giants_ghosts[index].id, giants_ghosts[l].id)); giants_and_ghosts (l+1 , index-1 ); giants_and_ghosts (index+1 , r); } int main (int argc, const char **argv) { int n; std::cin >> n; for (int _ = 0 ; _ < n; _++) { giant_ghost tp; std::cin >> tp.id >> tp.x >> tp.y; tp.is_giant = true ; giants_ghosts.push_back (tp); } for (int _ = 0 ; _ < n; _++) { giant_ghost tp; std::cin >> tp.id >> tp.x >> tp.y; tp.is_giant = false ; giants_ghosts.push_back (tp); } giants_and_ghosts (0 , giants_ghosts.size ()-1 ); for (const auto & pair : ans) { std::cout << pair.first << " " << pair.second << std::endl; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 #[derive(Clone, Copy)] struct GiantGhost { x : f64 , y : f64 , is_giant: bool , id: i32 } fn giants_and_ghosts (giants_ghosts : &mut [GiantGhost]) { if giants_ghosts.len () <= 0 { return ; } assert_eq! (giants_ghosts.len () % 2 , 0 ); if giants_ghosts.len () == 2 { assert! (giants_ghosts[0 ].is_giant || giants_ghosts[1 ].is_giant); assert! (!(giants_ghosts[0 ].is_giant && giants_ghosts[1 ].is_giant)); if giants_ghosts[0 ].is_giant { println! ("{} {}" , giants_ghosts[0 ].id, giants_ghosts[1 ].id); } else { println! ("{} {}" , giants_ghosts[1 ].id, giants_ghosts[0 ].id); } return ; } let mut index = 0 ; let mut left = giants_ghosts[0 ]; for i in 1 ..giants_ghosts.len () { if giants_ghosts[i].y < left.y || giants_ghosts[i].y == left.y && giants_ghosts[i].x < left.x { index = i; left = giants_ghosts[i]; } } left = giants_ghosts[0 ]; giants_ghosts[0 ] = giants_ghosts[index]; giants_ghosts[index] = left; left = giants_ghosts[0 ]; let slice = &mut giants_ghosts[1 ..]; slice.sort_by (|g1, g2| { let x1 = g1.x - g2.x; let y1 = g1.y - g2.y; let x2 = g2.x - left.x; let y2 = g2.y - left.y; let ans = x1 * y2 - x2 * y1; if ans == 0.0 { return std::cmp::Ordering::Equal; } else if ans > 0.0 { return std::cmp::Ordering::Less; } else { return std::cmp::Ordering::Greater; } }); let mut giant_cnt = if left.is_giant { 1 } else { 0 }; let mut ghost_cnt = if left.is_giant { 0 } else { 1 }; index = 0 ; loop { index += 1 ; assert! (index < giants_ghosts.len ()); if giants_ghosts[index].is_giant { giant_cnt += 1 ; } else { ghost_cnt += 1 ; } if giant_cnt == ghost_cnt { break ; } } if giants_ghosts[0 ].is_giant { println! ("{} {}" , giants_ghosts[0 ].id, giants_ghosts[index].id); } else { println! ("{} {}" , giants_ghosts[index].id, giants_ghosts[0 ].id); } if 1 < index-1 { giants_and_ghosts (&mut giants_ghosts[1 ..index]); } if index + 1 < giants_ghosts.len () { giants_and_ghosts (&mut giants_ghosts[(index+1 )..]); } } fn main () { let mut input = String ::new (); std::io::stdin ().read_line (&mut input).unwrap (); let n : i32 = input.trim ().parse ().unwrap (); let mut giants_ghosts : Vec <GiantGhost> = Vec ::new (); for _ in 0 ..n { input.clear (); std::io::stdin ().read_line (&mut input).unwrap (); while input.trim ().len () <= 0 { std::io::stdin ().read_line (&mut input).unwrap (); } let mut s = input.trim ().split (' ' ); let id : i32 = s.next ().unwrap ().trim ().parse ().unwrap (); let x : f64 = s.next ().unwrap ().trim ().parse ().unwrap (); let y : f64 = s.next ().unwrap ().trim ().parse ().unwrap (); giants_ghosts.push (GiantGhost {x, y,is_giant:true , id}); } for _ in 0 ..n { input.clear (); std::io::stdin ().read_line (&mut input).unwrap (); while input.trim ().len () <= 0 { std::io::stdin ().read_line (&mut input).unwrap (); } let mut s = input.trim ().split (' ' ); let id : i32 = s.next ().unwrap ().trim ().parse ().unwrap (); let x : f64 = s.next ().unwrap ().trim ().parse ().unwrap (); let y : f64 = s.next ().unwrap ().trim ().parse ().unwrap (); giants_ghosts.push (GiantGhost {x, y,is_giant:false , id}); } giants_and_ghosts (&mut giants_ghosts[..]); }