A:签到题,正常模拟即可。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1e5 + 5; 4 struct node{ 5 int id, time; 6 }; 7 node a[maxn]; 8 bool cmp(const node &a, const node &b){ 9 if(a.id^b.id) return a.id < b.id; 10 else return a.time < b.time; 11 } 12 int main() 13 { 14 std::ios::sync_with_stdio(false); 15 int n, m, t; 16 cin >> t; 17 for(int cas = 1;cas <= t;cas++) 18 { 19 cin >> n >> m; 20 for(int i = 0;i < n;i++) cin >> a[i].id; 21 for(int i = 0;i < n;i++) cin >> a[i].time; 22 int ans = 0;sort(a, a + n, cmp); 23 int sum = 0; 24 for(int i = 0;i < n;i++) 25 { 26 if(sum + a[i].time <= m) sum += a[i].time, ans ++; 27 else break; 28 } 29 cout << "Case " << cas << ": "; 30 cout<< ans << endl; 31 } 32 return 0; 33 }
B:对于差值尽量小的问题,可以采用枚举最小值,然后使得最大值尽量小。
首先二分图判定,然后分块,求出每块的光明状态的最大最小值,黑暗状态的最大最小值,然后按分块编号塞到线段树离维护最大值,然后对这2*cnt个块由最小值从小到大进行排序,枚举每个块的最小值,然后更新答案,然后将这个块的最大值在线段树中删去,当某个块的光明状态和黑暗状态都被删去的时候,就不用继续枚举了。
1 #include<bits/stdc++.h> 2 #define ls rt << 1 3 #define rs rt << 1 | 1 4 #define lr2 (l + r) >> 1 5 #define lson l, mid, rt << 1 6 #define rson mid + 1, r, rt << 1 | 1 7 using namespace std; 8 typedef long long ll; 9 const int maxn = 5e5 + 50; 10 const int INF = 0x3f3f3f3f; 11 struct node{ 12 int maxx, minn, id; 13 bool operator <(const node &b)const{ 14 return minn < b.minn; 15 } 16 }; 17 struct tree{ 18 pair<int, int> p[2]; 19 int val; 20 void deleted(int x) 21 { 22 if(p[0].first == x) p[0].second = INF; 23 else p[1].second = INF; 24 } 25 }; 26 int n, m, t; 27 vector<int> G[maxn]; 28 int L[maxn], D[maxn]; 29 int color[maxn] , vis[maxn], cnt; 30 tree T[maxn << 2]; 31 node A[maxn]; 32 bool flag; 33 int num[maxn]; 34 void pushup(int rt) 35 { 36 T[rt].val = max(T[ls].val, T[rs].val); 37 } 38 void build(int l, int r, int rt) 39 { 40 if(l == r) 41 { 42 T[rt].p[0] = {A[l].minn, A[l].maxx}; 43 T[rt].p[1] = {A[l + cnt].minn, A[l + cnt].maxx}; 44 T[rt].val = min(A[l].maxx, A[l + cnt].maxx); 45 return; 46 } 47 int mid = lr2; 48 build(lson); 49 build(rson); 50 pushup(rt); 51 } 52 void update(int k, int v, int l, int r, int rt){ 53 if(l == r){ 54 T[rt].deleted(v); 55 T[rt].val = min(T[rt].p[0].second, T[rt].p[1].second); 56 return; 57 } 58 int mid = lr2; 59 if(k <= mid) update(k, v, lson); 60 else update(k, v ,rson); 61 pushup(rt); 62 } 63 bool dfs(int v, int c, int id){ 64 color[v] = c; 65 vis[v] = id; 66 for(int i = 0;i < G[v].size();i++) 67 { 68 int u = G[v][i]; 69 if(color[u] == c) return false; 70 if(!color[u]){ 71 if(!dfs(u, 3 - c, id)) return false; 72 } 73 } 74 return true; 75 } 76 void init() 77 { 78 for(int i = 0;i <= n;i++) G[i].clear(); 79 fill(color, color + n + 100, 0); 80 fill(vis, vis + n + 100, 0); 81 fill(num, num + n + 100, 0); 82 cnt = 0;flag = false; 83 } 84 int main() 85 { 86 std::ios::sync_with_stdio(false); 87 cin >> t; 88 for(int cas = 1; cas <= t;cas++) 89 { 90 cin >> n >> m; 91 init(); 92 for(int i = 0;i < m;i++) 93 { 94 int a, b; cin >> a >> b; 95 G[a].push_back(b); 96 G[b].push_back(a); 97 } 98 for(int i = 1;i <= n;i++) cin >> L[i] >> D[i]; 99 for(int i = 1;i <= n;i++) 100 { 101 if(!vis[i]) 102 { 103 ++cnt; 104 if(!dfs(i, 1, cnt)) 105 { 106 flag = true; 107 break; 108 } 109 } 110 } 111 cout << "Case " << cas << ": "; 112 if(flag){ 113 cout << "IMPOSSIBLE" << endl; 114 continue; 115 } 116 for(int i = 1;i <= 2 * cnt;i++) 117 { 118 A[i].maxx = 0, A[i].minn = INF; 119 } 120 for(int i = 1;i <= n;i++){ 121 int x = vis[i]; 122 if(color[i] == 1) 123 { 124 A[x].id = x; 125 A[x].maxx = max(A[x].maxx, L[i]); 126 A[x].minn = min(A[x].minn, L[i]); 127 A[x + cnt].id = x; 128 A[x + cnt].maxx = max(A[x + cnt].maxx, D[i]); 129 A[x + cnt].minn = min(A[x + cnt].minn, D[i]); 130 } 131 else{ 132 A[x].id = x; 133 A[x].maxx = max(A[x].maxx, D[i]); 134 A[x].minn = min(A[x].minn, D[i]); 135 A[x + cnt].id = x; 136 A[x + cnt].maxx = max(A[x + cnt].maxx, L[i]); 137 A[x + cnt].minn = min(A[x + cnt].minn, L[i]); 138 } 139 } 140 build(1, cnt, 1); 141 sort(A + 1, A + 2 * cnt + 1); 142 int ans = INF; 143 for(int i = 1;i <= 2 * cnt;i++) 144 { 145 ans = min(ans, T[1].val - A[i].minn); 146 num[A[i].id]++; 147 if(num[A[i].id] == 2) break; 148 update(A[i].id, A[i].minn, 1, cnt, 1); 149 } 150 cout << ans << endl; 151 } 152 return 0; 153 }
G:题目大意:在一个n * m的土地,要在一个子矩形内放稻草人,稻草人必须被稻草包围,问合法的方法有多少种?
问题其实可以转化为:在n * m的草地上,选出一块子矩形,这个子矩形来放满稻草人必须被包括在n * m的矩形内。可以行和列分开考虑,(行的方案数) * (列的方案数)就是答案。一行可以选4个点,里面两个点是子矩形的宽的边界(列的边界),发现这样能确定一个子矩形的列的情况,但还有一种遗漏,就是只有一列的子矩形,这种情况只需要选三个点,所以是c[m][3] + c[m][4], 这样就确定了列的所有方案,行的方案跟列的方案类似。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 1e5 + 5; 5 const int mod = 1e9 + 7; 6 ll C[maxn][5]; 7 void init() 8 { 9 C[0][0] = 1; 10 for(int i = 1; i <= maxn;i++) 11 { 12 C[i][0] = 1; 13 for(int j = 1; j <= 4;j++) 14 C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod; 15 } 16 } 17 int main() 18 { 19 std::ios::sync_with_stdio(false); 20 int n, m ,t; 21 cin >> t; 22 init(); 23 for(int cas = 1;cas <= t;cas++) 24 { 25 cin >> n >> m; 26 ll h = (C[n][3] + C[n][4]) % mod; 27 ll w = (C[m][3] + C[m][4]) % mod; 28 ll ans = h * w % mod; 29 cout << "Case "<< cas << ": "; 30 cout << ans << endl; 31 } 32 return 0; 33 }
I:记录每个点的横纵坐标所在行列的点的数目,找到最大的maxx,maxy,max_x = maxx+maxy,其实消灭蟑螂的最大数目只能是max_x,或者max_x-1。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 1e5 + 5; 5 ll n; 6 map<int,int> x, y; 7 struct node{ 8 int x,y; 9 }; 10 node a[maxn]; 11 int main() 12 { 13 std::ios::sync_with_stdio(false); 14 int t; 15 cin >> t; 16 for(int cas = 1; cas <=t; cas++){ 17 cin >> n; 18 x.clear(); 19 y.clear(); 20 for(int i = 1; i <= n; i++){ 21 cin >> a[i].x >> a[i].y; 22 x[a[i].x]++; 23 y[a[i].y]++; 24 } 25 int maxx = 0, maxy = 0; 26 for(int i = 1; i <= n; i++){ 27 maxx = max(maxx, x[a[i].x]); 28 maxy = max(maxy, y[a[i].y]); 29 } 30 if(x.size() == 1 || y.size() == 1){ 31 cout << "Case " << cas << ": " << n << " " << 1 << endl; 32 } 33 else{ 34 if(maxx == 1 && maxy == 1){ 35 cout << "Case " << cas << ": " << 2 << " " << n*(n-1)/2 << endl; 36 } 37 else{ 38 ll x1 = 0, x2 = 0, y1 = 0, y2 = 0; 39 map<int,int>::iterator it; 40 for(it = x.begin(); it != x.end(); it++){ 41 if(it->second == maxx) x1++; 42 else if(it->second == maxx - 1) x2++; 43 } 44 for(it = y.begin(); it != y.end(); it++){ 45 if(it->second == maxy) y1++; 46 else if(it->second == maxy - 1) y2++; 47 } 48 ll ans1 = 0, ans2 = 0; 49 ans1 = x1 * y1; 50 ans2 = x2 * y1 + x1 * y2; 51 for(int i = 1; i <= n; i++){ 52 if(maxx + maxy == x[a[i].x] + y[a[i].y]){ 53 ans1--; 54 ans2++; 55 } 56 else if(maxx + maxy - 1 == x[a[i].x] + y[a[i].y]){ 57 ans2--; 58 } 59 } 60 if(ans1){ 61 cout << "Case " << cas << ": " << maxx + maxy << " " << ans1 << endl; 62 } 63 else{ 64 cout << "Case " << cas << ": " << maxx + maxy - 1 << " " << ans2 << endl; 65 } 66 } 67 } 68 } 69 70 71 }
L:贪心 + 分类讨论 + 暴力。小于等于11直接impossible, 然后奇数可以拆成 2 2 2 3 + 偶数, 偶数可以拆成2 2 2 2 + 偶数,对最后的偶数暴力分解即可。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 bool check(ll x) 5 { 6 int n = sqrt(x); 7 for(int i = 2;i <= n;i++){ 8 if(x % i == 0)return false; 9 } 10 return true; 11 12 } 13 void print(ll n) 14 { 15 for(ll i = n - 2;i >= 2;i--){ 16 if(check(i) && check(n - i)){ 17 cout << " " << i << " " << n - i << endl; 18 return; 19 } 20 } 21 } 22 int main() 23 { 24 std::ios::sync_with_stdio(false); 25 int t; 26 cin >> t; 27 int cnt = 1; 28 while(t--) 29 { 30 ll n; 31 cin >> n; 32 cout << "Case "<< cnt++ <<": "; 33 if(n > 11) 34 { 35 if(n & 1) 36 { 37 n -= 9LL; 38 cout << "2 2 2 3"; 39 print(n); 40 } 41 else{ 42 n -= 8LL; 43 cout << "2 2 2 2"; 44 print(n); 45 } 46 } 47 else cout << "IMPOSSIBLE" << endl; 48 } 49 return 0; 50 }
原文地址:https://www.cnblogs.com/Carered/p/11622883.html
时间: 2024-09-30 11:49:40