本题的重点在于计算两个矩形相交的面积。经过分析和观察可以发现,假如两个矩形左下角和右上角的坐标分别为 ( x 1 , y 1 ) , ( x 2 , y 2 ) (x_1,y_1), (x_2,y_2) ( x 1 , y 1 ) , ( x 2 , y 2 ) 和 ( x 3 , y 3 ) , ( x 4 , y 4 ) (x_3,y_3), (x_4, y_4) ( x 3 , y 3 ) , ( x 4 , y 4 ) ,同时两矩形相交,那么相交得到的矩形左下角坐标为:( max ( x 1 , x 3 ) , max ( y 1 , y 3 ) ) (\max(x_1,x_3), \max(y_1, y_3)) ( max ( x 1 , x 3 ) , max ( y 1 , y 3 )) ,右上角为 ( min ( x 2 , x 4 ) , min ( y 2 , y 4 ) ) (\min(x_2,x_4), \min(y_2,y_4)) ( min ( x 2 , x 4 ) , min ( y 2 , y 4 )) 。
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 #include <bits/stdc++.h> using namespace std;struct rectangle { rectangle () {} rectangle (int left, int bottom, int right, int top) { this ->left = left, this ->right = right; this ->bottom = bottom, this ->top = top; } int get_area () { return (right - left) * (top - bottom); } void resize (int left, int bottom, int right, int top) { this ->left = left, this ->right = right; this ->bottom = bottom, this ->top = top; } int left, right, bottom, top; }; bool is_insert (rectangle r1, rectangle r2) { if (r1.left >= r2.right || r2.left >= r1.right || r1.bottom >= r2.top || r2.bottom >= r1.top) return false ; return true ; } int insert_area (rectangle r1, rectangle r2) { if (!is_insert (r1, r2)) return 0 ; rectangle insert_r (max(r1.left, r2.left), max(r1.bottom, r2.bottom), min(r1.right, r2.right), min(r1.top, r2.top)) ; return insert_r.get_area (); } int main () { int n, a, b; scanf ("%d %d %d" , &n, &a, &b); int left, bottom, right, top; int area = 0 ; rectangle new_r (0 , 0 , a, b) , r ; for (int i = 0 ; i < n; i++) { scanf ("%d %d %d %d" , &left, &bottom, &right, &top); r.resize (left, bottom, right, top); area += insert_area (r, new_r); } printf ("%d" , area); }
对于一个结构体,假如需要定义其构造函数,有时需要注意重载一个默认构造函数。
本题只需假设一个最短的时间,然后不断计算查看已有资源是否足够即可。同时假定的最短时间使用二分法进行不断尝试。
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 #include <bits/stdc++.h> #include <vector> using namespace std;int n, m, k;vector<int > times; vector<int > com_resources; bool satisfy (int guess_time) { long long require_resource = 0 ; for (int i = 0 ; i < n; i++) { if (times[i] <= guess_time) continue ; require_resource += (times[i] - guess_time) * com_resources[i]; } if (require_resource <= m) return true ; else return false ; } int main () { int time, com_resource; int max_time = 0 ; scanf ("%d %d %d" , &n, &m, &k); for (int i = 0 ; i < n; i++) { scanf ("%d %d" , &time, &com_resource); if (time > max_time) max_time = time; times.push_back (time); com_resources.push_back (com_resource); } if (satisfy (k)) { printf ("%d" , k); return 0 ; } int left_bound = k, right_bound = max_time; int guess_time = (left_bound + right_bound) / 2 ; while (left_bound < right_bound) { if (satisfy (guess_time)) right_bound = guess_time; else left_bound = guess_time + 1 ; guess_time = (left_bound + right_bound) / 2 ; } printf ("%d" , guess_time); return 0 ; }
这里因为 n 的不确定性使用了 vector,事实上直接开一个足够大的数组也是可以的。
本题只要使用递归来解析语法即可。
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 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 #include <bits/stdc++.h> using namespace std;struct user_attr { int label = 0 ; int value = 0 ; }; struct user { int dn = 0 ; int attr_num = 0 ; user_attr attr[500 ]; }; user usr[2500 ]; string expr[500 ]; vector<int > matched_usr; int n, m; vector<int > translate_base_expr (string expr) ; vector<int > translate_expr (string expr) ; bool match_expr (int usr, int label, int value, bool positive) ; vector<int > get_union (const vector<int > &vec1, const vector<int > &vec2) ;vector<int > get_intersection (vector<int > vec1, vector<int > vec2) ;int main () { int attr_num; scanf ("%d" , &n); for (int i = 0 ; i < n; i++) { scanf ("%d%d" , &(usr[i].dn), &(usr[i].attr_num)); for (int j = 0 ; j < usr[i].attr_num; j++) scanf ("%d%d" , &(usr[i].attr[j].label), &(usr[i].attr[j].value)); } scanf ("%d" , &m); cin.get (); for (int i = 0 ; i < m; i++) getline (cin, expr[i]); for (int i = 0 ; i < m; i++) { matched_usr = translate_expr (expr[i]); sort (matched_usr.begin (), matched_usr.end ()); for (int usr_dn : matched_usr) printf ("%d " , usr_dn); printf ("\n" ); } } bool match_expr (int usr_id, int label, int value, bool positive) { int left = 0 , right = usr[usr_id].attr_num - 1 ; int i = (left + right) / 2 ; while (true ) { if (usr[usr_id].attr[i].label == label) break ; else if (usr[usr_id].attr[i].label > label) right = i - 1 ; else left = i + 1 ; if (left > right) return false ; i = (left + right) / 2 ; } if (positive) { if (usr[usr_id].attr[i].value == value) return true ; else return false ; } else { if (usr[usr_id].attr[i].value == value) return false ; else return true ; } } vector<int > translate_base_expr (string expr) { vector<int > selected_usr; selected_usr.reserve (2500 ); bool positive, overturn = false ; int value = 0 , label = 0 ; for (int i = 0 ; i < expr.length (); ++i) if (expr[i] >= '0' && expr[i] <= '9' ) { if (overturn) value = value * 10 + (expr[i] - '0' ); else label = label * 10 + (expr[i] - '0' ); } else { overturn = true ; if (expr[i] == ':' ) positive = true ; else if (expr[i] == '~' ) positive = false ; else printf ("DEBUG: something go wrong in operater!\n" ); } for (int i = 0 ; i < n; i++) if (match_expr (i, label, value, positive)) selected_usr.push_back (usr[i].dn); return selected_usr; } vector<int > translate_expr (string expr) { vector<int > selected_usr; selected_usr.reserve (2500 ); bool vec_union; int left_brac_cnt = 0 ; int second_expr_start, second_expr_len, first_expr_len, first_expr_start = 2 ; if (expr[0 ] != '&' && expr[0 ] != '|' ) return translate_base_expr (expr); if (expr[0 ] == '&' ) vec_union = false ; else if (expr[0 ] == '|' ) vec_union = true ; for (int i = 2 ; i < expr.length (); i++) if (expr[i] == '(' ) left_brac_cnt++; else if (expr[i] == ')' ) if (left_brac_cnt > 0 ) left_brac_cnt--; else if (left_brac_cnt == 0 && expr[i + 1 ] == '(' ) second_expr_start = i + 2 ; else printf ("DEBUG: something went wrong in bracket paring!\n" ); first_expr_len = (second_expr_start - 2 ) - first_expr_start; second_expr_len = (expr.length () - 1 ) - second_expr_start; string sub_expr1 = expr.substr (first_expr_start, first_expr_len); string sub_expr2 = expr.substr (second_expr_start, second_expr_len); vector<int > selected_usr1 = translate_expr (sub_expr1); vector<int > selected_usr2 = translate_expr (sub_expr2); if (vec_union) return get_union (selected_usr1, selected_usr2); else return get_intersection (selected_usr1, selected_usr2); } vector<int > get_union (const vector<int > &vec1, const vector<int > &vec2) { vector<int > result; result.reserve (vec1.size () + vec2.size ()); result.insert (result.end (), vec1.begin (), vec1.end ()); result.insert (result.end (), vec2.begin (), vec2.end ()); sort (result.begin (), result.end ()); result.erase (unique (result.begin (), result.end ()), result.end ()); return result; } vector<int > get_intersection (vector<int > vec1, vector<int > vec2) { vector<int > result; result.reserve (min (vec1.size (), vec2.size ())); sort (vec1.begin (), vec1.end ()); sort (vec2.begin (), vec2.end ()); int pointer1 = 0 , pointer2 = 0 ; while (pointer1 < vec1.size () && pointer2 < vec2.size ()) { if (vec1[pointer1] == vec2[pointer2]) { result.push_back (vec1[pointer1]); pointer1++; pointer2++; } else if (vec1[pointer1] > vec2[pointer2]) pointer2++; else pointer1++; } return result; }