4-10,广工校赛,一场坑爹的邂逅。。。。。。
首先,路程坑爹,问了好久路才到什么GUI工学馆。。。。
其次,天气坑爹,怎么老是下雨。。。。
最后,比赛坑爹,本垃圾被坑得不要不要的,为什么题A1小时前和一小时后看的是不一样的,改题面,改样例,恩,你倒不如新增一道题算了;为什么题C无解啊!广工:大家注意,没有这种数据(没有你放出来干*啊)。。。。
Problem A: Krito的讨伐
题意:略
题解:实质上是贪心模拟题,先从根节点往下走,把根节点的怪都消灭掉之后,在把它的儿子都加进来,最后看有没有打不过的就可以了。
代码怎么写呢?先用dfs从根出发,然后扫到一个有怪物的结点,加进去之后就退出来,不在dfs,从优先队列拿出元素之后,记录这个点有没有全部拿完怪兽,有的dfs这个点就好了。
1 /*zhen hao*/ 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 using namespace std; 9 10 typedef pair<int,int> pii; 11 const int maxn = 1e3 + 10; 12 int cnt[maxn], father[maxn]; 13 int n, m, k; 14 vector<int> tree[maxn]; 15 16 struct Node { 17 int id, d, a; 18 Node(int id=0, int d=0, int a=0) : id(id), d(d), a(a) {} 19 bool operator < (const Node& o) const { 20 return d > o.d; 21 } 22 }; 23 24 priority_queue<Node> pq; 25 vector<Node> mon[maxn]; 26 27 void dfs(int u, int fa) { 28 father[u] = fa; 29 if (!mon[u].empty()) { 30 for (int i = 0; i < (int)mon[u].size(); i++) pq.push(mon[u][i]); 31 return; 32 } 33 for (int i = 0; i < (int)tree[u].size(); i++) { 34 int v = tree[u][i]; 35 if (v == fa) continue; 36 dfs(v, u); 37 } 38 } 39 40 int main() { 41 // freopen("case.in", "r", stdin); 42 int T; 43 cin >> T; 44 while (T--) { 45 scanf("%d%d", &n, &m); 46 for (int i = 0; i < n; i++) tree[i].clear(), mon[i].clear(); 47 for (int i = 0; i < n - 1; i++) { 48 int u, v; 49 scanf("%d%d", &u, &v); 50 tree[u].push_back(v); 51 tree[v].push_back(u); 52 } 53 scanf("%d", &k); 54 for (int i = 0; i < m; i++) { 55 int x, y, z; 56 scanf("%d%d%d", &x, &y, &z); 57 mon[x].push_back(Node(x, y, z)); 58 } 59 60 while (!pq.empty()) pq.pop(); 61 62 dfs(0, -1); 63 memset(cnt, 0, sizeof cnt); 64 65 while (!pq.empty()) { 66 Node p = pq.top(); pq.pop(); 67 // cout << p.id << " " << p.d << " " << p.a << " " << pq.size() << endl; 68 if (k <= p.d) { k = -1; break; } 69 k += p.a; 70 int u = p.id; 71 if (++cnt[u] >= (int)mon[u].size()) { 72 for (int i = 0; i < (int)tree[u].size(); i++) { 73 int v = tree[u][i]; 74 if (v == father[u]) continue; 75 dfs(v, u); 76 } 77 } 78 } 79 // cout << k << endl; 80 if (k != -1) puts("Oh yes."); 81 else puts("Good Good Study,Day Day Up."); 82 } 83 }
代码君
Problem B: Sward Art Online
题意:略
题解:暴力水题,枚举首饰和头盔,枚举单手剑即可,dp1[i]表示用了i元钱能够买到最大首饰盒头盔的攻击力,dp2[i]表示用了i元钱能够买到最大的剑的攻击力,然后总结一下最大值即可。
注意两个坑点:第一id == -1 buff == -1buff无效,第二剑只有一把;
1 /*zhen hao*/ 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <iostream> 6 #include <vector> 7 #include <string> 8 #include <queue> 9 using namespace std; 10 11 struct Node { 12 int mon, atk, id, buff; 13 }; 14 15 Node A[110], B[110], C[110], D[110]; 16 int dp1[10010], dp2[10010]; 17 18 int main() { 19 // freopen("case.in", "r", stdin); 20 int T; 21 cin >> T; 22 while (T--) { 23 int m, a, b, c, d; 24 cin >> m >> a >> b >> c >> d; 25 memset(dp1, 0, sizeof dp1); 26 memset(dp2, 0, sizeof dp2); 27 28 for (int i = 0; i < a; i++) { 29 scanf("%d%d", &A[i].mon, &A[i].atk); 30 dp1[A[i].mon] = max(dp1[A[i].mon], A[i].atk); 31 } 32 for (int i = 0; i < b; i++) { 33 scanf("%d%d%d%d", &B[i].mon, &B[i].atk, &B[i].id, &B[i].buff); 34 dp1[B[i].mon] = max(dp1[B[i].mon], B[i].atk); 35 } 36 for (int i = 0; i < c; i++) { 37 scanf("%d%d", &C[i].mon, &C[i].atk); 38 dp2[C[i].mon] = max(dp2[C[i].mon], C[i].atk); 39 } 40 for (int i = 0; i < d; i++) { 41 scanf("%d%d", &D[i].mon, &D[i].atk); 42 dp2[D[i].mon] = max(dp2[D[i].mon], D[i].atk); 43 } 44 45 for (int i = 0; i < a; i++) 46 for (int j = 0; j < b; j++) { 47 int temp; 48 if (B[j].buff != -1 && B[j].id == i) temp = A[i].atk + B[j].atk + B[j].buff; 49 else temp = A[i].atk + B[j].atk; 50 dp1[A[i].mon + B[j].mon] = max(dp1[A[i].mon + B[j].mon], temp); 51 } 52 53 for (int i = 0; i < c; i++) 54 for (int j = 0; j < i; j++) 55 dp2[C[i].mon + C[j].mon] = max(dp2[C[i].mon + C[j].mon], C[i].atk + C[j].atk); 56 57 for (int i = 1; i <= m; i++) { 58 dp1[i] = max(dp1[i], dp1[i - 1]); 59 dp2[i] = max(dp2[i], dp2[i - 1]); 60 } 61 int ans = 0; 62 for (int i = 0; i <= m; i++) { 63 ans = max(ans, dp1[i] + dp2[m - i]); 64 ans = max(ans, dp1[i]); 65 ans = max(ans, dp2[i]); 66 } 67 cout << ans << endl; 68 } 69 return 0; 70 }
代码君
Problem C: wintermelon的魔界寻路之旅
题意:略
题解:连成一个有向图,然后跑dij之后,看最短路有多少条即可。
1 /*zhen hao*/ 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <iostream> 6 #include <vector> 7 #include <string> 8 #include <queue> 9 using namespace std; 10 11 const int maxn = 1e2 + 10, maxp = 1e4 + 10, inf = 1 << 30, mod = 1e9 + 9; 12 const int dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0}; 13 int head[maxp], dist[maxp], done[maxp], dp[maxp]; 14 int n, src, target, tot; 15 int val[maxn][maxn], id[maxn][maxn]; 16 17 struct Edge { 18 int v, w, next; 19 Edge(int v = 0, int w = 0, int next = 0) : v(v), w(w), next(next) {} 20 } edges[maxp * 100]; 21 22 struct Node { 23 int d, u; 24 Node(int d = 0, int u = 0) : d(d), u(u) {} 25 bool operator < (const Node& o) const { 26 return d > o.d; 27 } 28 }; 29 30 void init() { 31 memset(head, -1, sizeof head); 32 tot = 0; 33 } 34 35 void add_edge(int u, int v, int w) { 36 edges[tot] = Edge(v, w, head[u]); 37 head[u] = tot++; 38 } 39 40 void dijkstra() { 41 priority_queue<Node> pq; 42 memset(done, 0, sizeof done); 43 for (int i = src; i <= target; i++) dist[i] = inf; 44 dist[src] = 0; 45 pq.push(Node(0, src)); 46 while (!pq.empty()) { 47 Node r = pq.top(); pq.pop(); 48 int u = r.u; 49 if (done[u]) continue; 50 done[u] = true; 51 for (int i = head[u]; ~i; i = edges[i].next) { 52 Edge e = edges[i]; 53 if (dist[e.v] > dist[u] + e.w) { 54 dist[e.v] = dist[u] + e.w; 55 pq.push(Node(dist[e.v], e.v)); 56 } 57 } 58 } 59 } 60 61 void print() { 62 for (int i = src; i <= target; i++) { 63 printf("%d: ", i); 64 for (int j = head[i]; ~j; j = edges[j].next) { 65 printf("(%d %d) ", edges[j].v, edges[j].w); 66 } 67 puts(""); 68 } 69 } 70 71 int walk(int u) { 72 if (u == target) return 1; 73 if (dp[u] != -1) return dp[u]; 74 int& ret = dp[u]; 75 ret = 0; 76 for (int i = head[u]; ~i; i = edges[i].next) { 77 Edge e = edges[i]; 78 if (dist[u] + e.w == dist[e.v]) { 79 ret += walk(e.v); 80 if (ret >= mod) ret -= mod; 81 } 82 } 83 return ret; 84 } 85 86 int main() { 87 // freopen("case.in", "r", stdin); 88 int T; 89 cin >> T; 90 while (T--) { 91 scanf("%d", &n); 92 for (int i = 0; i < n; i++) 93 for (int j = 0; j < n; j++) { 94 scanf("%d", &val[i][j]); 95 } 96 97 for (int i = 0, k = n - 1; i < n; i++, k--) 98 for (int j = 0, l = n - 1; j < n - i - 1; j++, l--) 99 val[i][j] += val[l][k]; 100 101 src = 0, target = 0; 102 init(); 103 for (int i = 0; i < n; i++) 104 for (int j = 0; j < n - i; j++) 105 id[i][j] = target++; 106 107 for (int i = 0; i < n; i++) 108 for (int j = 0; j < n - i; j++) { 109 int u = id[i][j]; 110 // cout << i << " " << j << " " << id[i][j] << targetl; 111 for (int k = 0; k < 4; k++) { 112 int ii = i + dx[k], jj = j + dy[k]; 113 if (ii >= 0 && ii < n && jj >= 0 && jj < n - ii) { 114 int v = id[ii][jj]; 115 add_edge(u, v, val[ii][jj]); 116 } 117 } 118 } 119 120 for (int i = 0; i < n; i++) { 121 int x = id[i][n - i - 1]; 122 add_edge(x, target, 0); 123 add_edge(target, x, 0); 124 } 125 if (target >= maxp || tot > maxp * 100) { 126 while (true); 127 } 128 129 // print(); 130 dijkstra(); 131 memset(dp, -1, sizeof dp); 132 printf("%d\n", walk(src)); 133 } 134 return 0; 135 }
代码君
Problem F: 我是好人4
题意:略
题解:容斥+dfs枚举子集。不能用位来枚举,因为有个关键的剪枝就是:如果这个数大于le9就不用再继续枚举下去了,这样想想,好像真的很小的复杂度,因为还有个去重,就是如果aj是某个ai的备受,那么就不用管这个aj;挺好的一道题。
1 /*zhen hao*/ 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 8 typedef long long ll; 9 const int maxn = 60, con = 1e9; 10 int v[maxn], nv[maxn]; 11 int n, cnt, ans; 12 13 int gcd(int a, int b) { 14 if (!b) return a; 15 return gcd(b, a % b); 16 } 17 18 void dfs(int now, int cur, ll LCM) { 19 if (cur >= cnt) { 20 if (now) ans += (con / LCM) * (now & 1 ? -1 : 1); 21 return; 22 } 23 if (LCM > con) return; 24 dfs(now, cur + 1, LCM); 25 if (now) { 26 if (LCM % nv[cur]) LCM *= nv[cur] / gcd(nv[cur], LCM); 27 dfs(now + 1, cur + 1, LCM); 28 } else { 29 dfs(now + 1, cur + 1, nv[cur]); 30 } 31 } 32 33 int main() { 34 // freopen("case.in", "r", stdin); 35 int T; 36 scanf("%d", &T); 37 while (T--) { 38 scanf("%d", &n); 39 for (int i = 0; i < n; i++) scanf("%d", v + i); 40 cnt = 0; 41 sort(v, v + n); 42 43 if (v[0] == 1) { 44 puts("0"); continue; 45 } 46 47 for (int i = 0; i < n; i++) { 48 bool ok = true; 49 for (int j = 0; j < i; j++) if (v[i] % v[j] == 0) ok = false; 50 if (ok) nv[cnt++] = v[i]; 51 } 52 ans = con; 53 dfs(0, 0, 1); 54 printf("%lld\n", ans); 55 } 56 return 0; 57 }
代码君
时间: 2024-10-12 07:46:58