记一次坑爹的广工校赛

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

记一次坑爹的广工校赛的相关文章

广工校赛——slamdunk正在做菜

Description 广工的slamdunk可谓是人生赢家,据传说他现在即将拥有一个girlfriend,并且在感情的驱使下他甚至开始学起了做菜! 现在他想为girlfriend做N道菜,每道菜做出来需要Ai分钟,slamdunk一分钟最多能煮M道菜,请问他做完这N道菜所需的最短时间 是多少?(如果你能帮他解决这个问题,他和他的girlfriend会送给你一个精美的气球~) Input 第一行输入一个整数T表示测试数据共有T(1 <= T <=10)组 每组测试数据的第一行有一个正整数N(1

广工校赛——GG的匹配串

Description 2015年广东工业大学ACM校赛要来~\(≧▽≦)/~辣辣辣,作为校赛的出题人之一,GG想出了一道水题来考考大家.相信小伙伴们都学过字符串匹配,于是字符串匹配的水题就诞生辣!GG给出了一段长度为N的大写字母序列,现在他要你修改这一段字母序列,使得这段字母序列上最前面的K个字母组成的序列与最后面的K个字母组成的序列一一匹配.  例如对于序列“ATUUUUAC”和K = 2,可以通过将第二个字母修改为“C”,使得最前面的两个字母与最后面的两个字母都为“AC”,当然 还存在其他

余数 2015广工校赛 C 魔幻任务

题目传送门 题意:问n位最小能整除47的数字 分析:打表发现前面都是100000...,后两位就是100000%47后到47的距离,就是快速幂求1000000%47的值,47-它就是后两位 #include <bits/stdc++.h> using namespace std; const int A = 47; int pow_mod(int x, int n, int p) { int ret = 1; while (n) { if (n & 1) ret = 1ll * ret

广工校赛——并查集——变形金刚

Description 有一天Stubird买了一台变形金刚,店员说,这台变形金刚和其他那种骗小孩子的不一样 他真的能变形. 这台变形金刚有n个部件,他们能互相连接,组成机器人,当然,也可以变形. 但是有一天,The tesseract 的能量突然消失了,部件散落一地,当然有些部件还连接着. 现在你只有把部件全部连接起来,他就能变回原样,例如,有4个部件,1,2是连接的,3,4也是连接着的 ,你只需要把1和3连接起来(1,4或者2,3或者2,4)他就能变回原样啦. 他现在问你最少需要多少次连接才

广工校赛决赛之简单的数论题

题目链接:F: 我是好人,题目大意:给你两个数 n 和 m,问你有多少对正整数对最大公约数是n,最小公倍数是m. 因为1 <= n, m <= 10000000000,暴力法肯定超时的,比赛时我也想到了把 n 和 m 分解开,质因数和对应的指数存放在 map 中,思路是正确的,可没想到在一些细节问题上没考虑周全,在没有判断 n 和 m 是否互质前就盲目地把它们进行分解,结果当然是wa了数遍,亏我还在苦苦思索是不是思路出错了,直至今天与文聪讨论时才发现这个瑕疵.用朴素的分解方法已经能够在时限范围

广工校赛——DP——悦动达人

Description 一个游戏,在屏幕上有5个格子形成一行,每一秒都会有一个格子闪烁,格子闪烁时你需要保证至少有一只手指在格子上面, 现在我们已经知道第i秒时,第xi个格子会闪烁,我们假设手指的移动不花费时间,你现在用两根手指玩这个游戏, 设初始两根手指都在0处位置,算出n秒过后手指需要移动的最小距离.(允许手指交叉) 注:手指移动的距离的计算是,假设你的一根从x,移动到y格,那么移动的距离是|x-y| Input 第一行一个数T,表示有T组测试数据(T<=50) 第二行,n,表示进行n秒(1

广工校赛——LCS——完美串

Description 爱美之心人皆有之,GG也不例外.所以GG他对于完美串有一种热衷的爱.在GG眼中完美串是一个具有无比魅力的01子串.这个子串有之其魅力之处,对它取反后水平翻转,它又和它原来的一模一样.这就是GG热爱它的原因.但是世上并不是所有的01串都是完美串,所以GG下定决心想改造01串,使所有的01串都成为完美串.但是改造01串是一个巨大的工程,GG太忙了,他还差T个01串未改造,他需要你的帮助.而你只需要告诉它至少添加几个'0','1'字符就可以使得01串成为完美串. Input 有

广工校赛——漂洋过海来看你

Description BMan和hyx住在一个神奇的国度,这个国度有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来. 现在BMan在第S号城市,他经常想起那个一起AC过的队友hyx,记忆它总是慢慢的累积,在他心中无法抹去,可是他并不知道hyx 在哪个城市,所以他决定用尽半年的积蓄漂洋过海去找hyx,现在BMan很想知道如果他想去hyx所在的第X号城市,必须经过的前 一个城市是第几号城市(放心,由于心系队友,BMan是不会选择走重复的路的~) Input 第一行输入一个整数T表示测试

广工校赛——游戏王

Description 小学的时候,Stubird非常喜欢玩游戏王,有一天,他发现了一个绝佳的连锁组合,这个连锁组合需要6张卡, 可是他一张都没有,但是他的那些朋友们有,不过当然,他们不会白给,不过也不排除有人和他交情好,送给他了. 不过他们有成全别人的美德,当他们看到Stubird已经有某些他们喜欢的卡的时候,他们会给他优惠,或者更贵也说不定 嘛不过,你可以把有的卡片藏起来,不告诉他们,来获得更低的价格. 问他最少需要多少钱才可以集齐所有的卡. Input 第一行T,表示有T个测试样例 第二行