zoukankan      html  css  js  c++  java
  • 记一次坑爹的广工校赛

    6/6

    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
    ", 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
    ", ans);
    55   }
    56   return 0;
    57 }
    代码君
  • 相关阅读:
    记录一次电话面试
    记录一次git合并
    HTML通用属性与常见标签
    位运算的应用
    HTML总结
    前端MVC
    常用软件
    docker常用命令
    composer install(update)时出现killed
    优化小技巧:该怎么识别百度蜘蛛呢
  • 原文地址:https://www.cnblogs.com/zhenhao1/p/5382106.html
Copyright © 2011-2022 走看看