2018 China Collegiate Programming Contest Final (CCPC-Final 2018)(A B G I L)
Posted carered
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018 China Collegiate Programming Contest Final (CCPC-Final 2018)(A B G I L)相关的知识,希望对你有一定的参考价值。
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
以上是关于2018 China Collegiate Programming Contest Final (CCPC-Final 2018)(A B G I L)的主要内容,如果未能解决你的问题,请参考以下文章
Fight Against Monsters (2018-2019 ACM-ICPC, China Multi-Provincial Collegiate Programming Contest)(T
2018 China Collegiate Programming Contest - Guilin Site(D/H/G/J/A)
2018 China Collegiate Programming Contest - Guilin Site(D/H/G/J/A)
2018 China Collegiate Programming Contest - Guilin Site(D/H/G/J/A)
Rolling The Polygon (2018-2019 ACM-ICPC, China Multi-Provincial Collegiate Programming Contest)(The
2018-2019 ACM-ICPC, China Multi-Provincial Collegiate G. Factories(树形dp+算贡献)