西安邮电第五届校赛
A.拯救咕咕咕之史莱姆
链接:https://ac.nowcoder.com/acm/contest/5678/A
可以算出来史莱姆每天减的血量
第一天:3
第二天:6
第三天:9
第四天:12
第五天:18
第六天:27
总和为:75
因此当血量<= 75 就会求饶
#include<bits/stdc++.h> using namespace std; typedef long long ll; int main() { ll n; while(cin >> n, n) { if(n <= 75) puts("AOLIGEI!"); else puts("DAAAAAMN!"); } return 0; }
校车
链接:https://ac.nowcoder.com/acm/contest/5678/G
离散差分
#include<bits/stdc++.h> using namespace std; typedef pair<int, int> pii; const int N = 100010; vector<pii> segs; vector<int> alls; int a[N]; unordered_set<int> much; int T, query; void insert(int l, int r) { a[l] += 1; a[r] -= 1; } int main() { scanf("%d", &T); while(T--) { scanf("%d", &query); while(query--) { int x, y; scanf("%d%d", &x, &y); segs.push_back({x, y}); alls.push_back(x); alls.push_back(y); if(!much.count(x)) much.insert(x); if(!much.count(y)) much.insert(y); } sort(alls.begin(), alls.end()); alls.erase(unique(alls.begin(), alls.end()), alls.end()); for(auto seg : segs) { int x = lower_bound(alls.begin(), alls.end(), seg.first) - alls.begin() + 1; int y = lower_bound(alls.begin(), alls.end(), seg.second) - alls.begin() + 1; insert(x, y); } for(int i = 1; i <= alls.size(); i++) a[i] += a[i - 1]; sort(a + 1, a + 1 + alls.size()); printf("%d %d\n", much.size(), a[alls.size()]); much.clear(); segs.clear(); memset(a, 0, sizeof a); } return 0; }
无敌阿姨
链接:https://ac.nowcoder.com/acm/contest/5678/E
#include<bits/stdc++.h> using namespace std; const int N = 105; int a[N]; int main() { int T; scanf("%d", &T); while(T--) { int n, m, k; int sum = 0; scanf("%d%d%d", &n, &m, &k); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); sum += a[i]; } int ans = 0, res; int now = 0; while(now < sum) { ans++; res = m; for(int i = 1; i <= n; i++) { if(a[i]) { while(a[i] && res) { a[i]--; res--; now++; } if(res <= k) break; res -= k; } } } printf("%d\n", ans); } return 0; }
烦人的依赖
链接:https://ac.nowcoder.com/acm/contest/5678/B
软件之间的依赖关系看成又向无环图,题目要按字典序排因此要用优先队列小根堆进行存储。
#include<bits/stdc++.h> using namespace std; const int N = 30010; int T, n, m, cnt, an; string s, t; string soft[N]; int in[N]; //入度数 vector<int> edge[N]; priority_queue<int, vector<int>, greater<int> > heap; //由于当软件等级一样时按照字典序从小到大排, 因此用小根堆 int ans[N]; unordered_map<string, int> mp; //需要将软件映射成数字才能进行连边 void init() { //由于多组数据进行输入 要对整体进行初始化 memset(in, 0, sizeof in); //度数初始化 while(!heap.empty()) //堆的初始化 heap.pop(); for(int i = 1; i <= n; i++) //对边的初始化 edge[i].clear(); mp.clear(); //映射初始化 cnt = 0; //topsort 的点数 } void solve() { scanf("%d%d", &n, &m); init(); for(int i = 1; i <= n; i++) cin >> soft[i]; sort(soft + 1, soft + 1 + n); //从小到大排序 for(int i = 1; i <= n; i++) //进行赋值 mp[soft[i]] = i; for(int i = 1; i <= m; i++) { cin >> s >> t; ++in[mp[t]]; //入度++ edge[mp[s]].push_back(mp[t]); //连边 } for(int i = 1; i <= n; i++) //将入度为0的存入堆中 if(!in[i]) heap.push(i); while(!heap.empty()) { int t = heap.top(); heap.pop(); ans[++cnt] = t; //用来存最终的答案 for(auto v : edge[t]) { //遍历边 if(!(--in[v])) heap.push(v); //入度为0存入队列 } } printf("Case #%d:\n", ++an); if(cnt != n) { //若点数不服则不存在 printf("Impossible\n"); return ; } for(int i = 1; i <= cnt; i++) cout << soft[ans[i]] << endl; } int main() { scanf("%d", &T); while(T--) { solve(); } return 0; }
异或生成树
dp[i][j]表示以i为节点能异或出来的值, 1表示能够组成出来,0表示不能够组成出来
由于是异或因此范围是0-127
状态转移方程为dp[u][i ^ j] = dp[u][i] & dp[v][j];
代码如下
#include<bits/stdc++.h> using namespace std; const int N = 105, M = 1 << 7; int n; vector<int> G[N]; int ans = 0, a[N], dp[N][M], tmp[M]; void dfs(int u, int f) { dp[u][a[u]] = 1; //由于u存在这样的点a[u] 因此赋值为1 for(auto v : G[u]) { if(v != f) { dfs(v, u); memset(tmp, 0, sizeof tmp); //将其初始化为0,让tmp 和 dp 去或(|) 判断这样的点是否存在 for(int i = 0; i < 128; i++) { for(int j = 0; j < 128; j++) //u 为父节点 v 为子节点 若存在 &上为1 tmp|上为1 tmp[i ^ j] |= dp[u][i] & dp[v][j]; //这一步求出父节点和子节点的异或的值有哪些 } for(int i = 0; i < 128; i++) //对dp的值进行更新 dp[u][i] |= tmp[i]; } } for(int i = 0; i < 128; i++) if(dp[u][i]) ans = max(ans, i); //找到最大值 } int main() { scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); for(int i = 1; i < n; i++) { int x, y; scanf("%d%d", &x, &y); G[x].push_back(y); G[y].push_back(x); } dfs(1, -1); printf("%d", ans); return 0; }