zoukankan      html  css  js  c++  java
  • 福州大学第十三届程序设计竞赛_重现

    8/9

    Problem A Calculus Midterm

    题意:略

    题解:~~

     

    Problem B 翻翻棋

    题意:略

    题解:~~

     

    Problem C 平行四边形数

    题意:略

    题解:~~

     

    Problem D 炉石传说

    题意:略

    题解:最直接的一个做法就是二分图,跑一遍判断是否匹配的数量为n。还可以的一个做法是贪心:先把对手的血量从大到小排,然后对于自己,选一个能满足对方攻击的自身攻击力最小的一个随从,然后不断重复,最后判断有无可选即可。

     

     1 /*zhen hao*/
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <iostream>
     5 using namespace std;
     6 
     7 #define lson l, m, rt << 1
     8 #define rson m + 1, r, rt << 1 | 1
     9 #define ll long long
    10 #define xx first
    11 #define yy second
    12 
    13 const int maxn = 110;
    14 int n, from[maxn], used[maxn];
    15 int G[maxn][maxn], a[maxn], b[maxn], c[maxn], d[maxn];
    16 
    17 bool is_match(int u) {
    18   for (int v = 0; v < n; v++) if (G[u][v] && !used[v]) {
    19     used[v] = 1;
    20     if (from[v] == -1 || is_match(from[v])) {
    21       from[v] = u;
    22       return true;
    23     }
    24   }
    25   return false;
    26 }
    27 
    28 int max_match() {
    29   int ret = 0;
    30   memset(from, -1, sizeof from);
    31   for (int i = 0; i < n; i++) {
    32     memset(used, 0, sizeof used);
    33     ret += is_match(i);
    34   }
    35   return ret;
    36 }
    37 
    38 int main() {
    39 //  freopen("case.in", "r", stdin);
    40   int T;
    41   cin >> T;
    42   while (T--) {
    43     scanf("%d", &n);
    44     for (int i = 0; i < n; i++) scanf("%d%d", a + i, b + i);
    45     for (int i = 0; i < n; i++) scanf("%d%d", c + i, d + i);
    46     memset(G, 0, sizeof G);
    47     for (int i = 0; i < n; i++)
    48       for (int j = 0; j < n; j++) {
    49         if (a[i] - d[j] > 0 && c[j] - b[i] <= 0) G[i][j] = 1;
    50       }
    51     if (max_match() == n) puts("Yes"); else puts("No");
    52   }
    53   return 0;
    54 }
    代码君(二分图)

     

     1 /*zhen hao*/
     2 #include <cstdio>
     3 #include <vector>
     4 #include <cstring>
     5 #include <queue>
     6 #include <algorithm>
     7 using namespace std;
     8 
     9 #define lson l, m, rt << 1
    10 #define rson m + 1, r, rt << 1 | 1
    11 #define xx first
    12 #define yy second
    13 
    14 typedef pair<int,int> pii;
    15 typedef long long ll;
    16 const int maxn = 110, inf = 1 << 20;
    17 int n;
    18 
    19 struct Node {
    20   int x, y, isdeath;
    21   Node(int x=0, int y=0, int isdeath=0) : x(x), y(y), isdeath(isdeath) {}
    22   bool operator < (const Node& o) const {
    23     return x > o.x;
    24   }
    25 };
    26 
    27 Node a[maxn], b[maxn];
    28 
    29 bool check() {
    30   for (int i = 0; i < n; i++) {
    31     int best = inf, bestid;
    32     for (int j = 0; j < n; j++) if (!a[j].isdeath) {
    33       if (a[j].x - b[i].y > 0 && b[i].x - a[j].y <= 0) {
    34         if (best > a[j].x) best = a[bestid = j].x;
    35       }
    36     }
    37     if (best == inf) return false;
    38     a[bestid].isdeath = 1;
    39   }
    40   return true;
    41 }
    42 
    43 int main() {
    44 //  freopen("case.in", "r", stdin);
    45   int T;
    46   scanf("%d", &T);
    47   while (T--) {
    48     scanf("%d", &n);
    49     for (int i = 0; i < n; i++) scanf("%d%d", &a[i].x, &a[i].y);
    50     for (int i = 0; i < n; i++) scanf("%d%d", &b[i].x, &b[i].y);
    51     for (int i = 0; i < n; i++) a[i].isdeath = b[i].isdeath = 0;
    52     sort(b, b + n);
    53     check() ? puts("Yes") : puts("No");
    54   }
    55   return 0;
    56 }
    代码君(贪心)

     

    Problem E ~APTX4869

    题意:略

    题解:对于这种最小值最大化的问题,用二分答案来处理。先二分出一个答案,然后对于每一对点如果小于这个答案那么一定要放在同一个集合,所以就连一条边代表这两个点一定是同一集合,然后最后dfs一个点,把能够标记的点都标记,最后看有没有剩下点,有的话就说明这个方案是合法的,否则不合法,然后不断往下分。

     

     1 /*zhen hao*/
     2 #include <vector>
     3 #include <cstring>
     4 #include <cstdio>
     5 using namespace std;
     6 
     7 #define lson l, m, rt << 1
     8 #define rson m + 1, r, rt << 1 | 1
     9 #define ll long long
    10 #define xx first
    11 #define yy second
    12 
    13 const int maxn = 8e2 + 10;
    14 int v[maxn][maxn], id[maxn], n;
    15 vector<int> G[maxn];
    16 
    17 void dfs(int u) {
    18   id[u] = 1;
    19   for (int i = 0; i < (int)G[u].size(); i++) {
    20     int v = G[u][i];
    21     if (id[v] == -1) dfs(v);
    22   }
    23 }
    24 
    25 bool check(int M) {
    26   for (int i = 0; i < n; i++) { G[i].clear(); id[i] = -1; }
    27   for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) if (i != j && v[i][j] < M)
    28     G[i].push_back(j);
    29   dfs(0);
    30   for (int i = 0; i < n; i++) if (id[i] == -1) return 1;
    31   return 0;
    32 }
    33 
    34 int main() {
    35 //  freopen("case.in", "r", stdin);
    36   while (scanf("%d", &n) == 1) {
    37     int L = 0, R = 0;
    38     for (int i = 0; i < n; i++)
    39       for (int j = 0; j < n; j++) {
    40         scanf("%d", &v[i][j]);
    41         R = max(R, v[i][j]);
    42       }
    43 
    44     while (L <= R) {
    45       int M = (L + R) / 2;
    46       if (check(M)) L = M + 1;
    47       else R = M - 1;
    48     }
    49     printf("%d
    ", R);
    50   }
    51 }
    代码君

     

    Problem F 牧场物语

    题意:略

    题解:dp[i][j][k]表示走了i步,然后第一次走停留在j行,第二次走停留在k行,为什么要这样呢?首先他要求的是最短路,所以一定是dp(否则可以用网络流)。然后就是当步数和行数确定的时候对应的列也是确定的。状态转移就四种,下下,下右,右下,右右。

     

     1 /*zhen hao*/
     2 #include <cstdio>
     3 #include <iostream>
     4 using namespace std;
     5 
     6 #define lson l, m, rt << 1
     7 #define rson m + 1, r, rt << 1 | 1
     8 #define ll long long
     9 #define xx first
    10 #define yy second
    11 
    12 const int maxn = 110;
    13 const ll inf = 1LL << 60;
    14 ll dp[maxn << 1][maxn][maxn], v[maxn][maxn];
    15 
    16 void init(int n) {
    17   for (int i = 0; i < 2 * n; i++)
    18     for (int j = 0; j < n; j++)
    19       for (int k = 0; k < n; k++)
    20         dp[i][j][k] = -inf;
    21 }
    22 
    23 int main() {
    24 //  freopen("case.in", "r", stdin);
    25   int n;
    26   while (scanf("%d", &n) == 1) {
    27     for (int i = 0; i < n; i++)
    28       for (int j = 0; j < n; j++)
    29         scanf("%I64d", &v[i][j]);
    30 
    31     init(n);
    32     dp[0][0][0] = v[0][0];
    33 
    34     for (int i = 0; i < 2 * n - 2; i++)
    35       for (int j = 0; j < n; j++)
    36         for (int k = 0; k < n; k++) if (dp[i][j][k] != -inf) {
    37           int jj = i - j, kk = i - k;
    38 //          cout << j << ' ' << jj << ' ' << k << ' ' << kk << endl;
    39           if (j != n - 1 && k != n - 1) {
    40             if (j != k) dp[i + 1][j + 1][k + 1] = max(dp[i + 1][j + 1][k + 1], dp[i][j][k] + v[j + 1][jj] + v[k + 1][kk]);
    41             else dp[i + 1][j + 1][k + 1] = max(dp[i + 1][j + 1][k + 1], dp[i][j][k] + v[j + 1][jj]);
    42           }
    43           if (j != n - 1 && kk != n - 1) {
    44             if (j + 1 != k) dp[i + 1][j + 1][k] = max(dp[i + 1][j + 1][k], dp[i][j][k] + v[j + 1][jj] + v[k][kk + 1]);
    45             else dp[i + 1][j + 1][k] = max(dp[i + 1][j + 1][k], dp[i][j][k] + v[j + 1][jj]);
    46           }
    47           if (jj != n - 1 && k != n - 1) {
    48             if (j != k + 1) dp[i + 1][j][k + 1] = max(dp[i + 1][j][k + 1], dp[i][j][k] + v[j][jj + 1] + v[k + 1][kk]);
    49             else dp[i + 1][j][k + 1] = max(dp[i + 1][j][k + 1], dp[i][j][k] + v[j][jj + 1]);
    50           }
    51           if (jj != n - 1 && kk != n - 1) {
    52             if (j != k) dp[i + 1][j][k] = max(dp[i + 1][j][k], dp[i][j][k] + v[j][jj + 1] + v[k][kk + 1]);
    53             else dp[i + 1][j][k] = max(dp[i + 1][j][k], dp[i][j][k] + v[j][jj + 1]);
    54           }
    55         }
    56     printf("%I64d
    ", dp[2 * n - 2][n - 1][n - 1]);
    57   }
    58   return 0;
    59 }
    代码君

     

    Problem G 国王的出游

    题意:略

    题解:这道题咋一眼看好像要离散化模拟什么的,实际上所有的线状区域长度不超过10 ^ 5就说明可以直接进行bfs,对于找点可以放在一个数组然后二分查找一下有没有这个点即可。

     

     1 /*zhen hao*/
     2 #include <cstdio>
     3 #include <vector>
     4 #include <cstring>
     5 #include <queue>
     6 #include <algorithm>
     7 using namespace std;
     8 
     9 #define lson l, m, rt << 1
    10 #define rson m + 1, r, rt << 1 | 1
    11 #define ll long long
    12 #define xx first
    13 #define yy second
    14 
    15 typedef pair<int,int> pii;
    16 const int maxn = 1e5 + 10;
    17 int sx, sy, ex, ey, cnt;
    18 pii p[maxn];
    19 bool vis[maxn];
    20 
    21 struct Node {
    22   int x, y, d;
    23   Node(int x=0,int y=0, int d=0) : x(x), y(y), d(d) {}
    24 };
    25 
    26 int bfs() {
    27   queue<Node> q;
    28   q.push(Node(sx, sy, 0));
    29   memset(vis, false, sizeof vis);
    30   pii tp = make_pair(sx, sy);
    31   int k = lower_bound(p, p + cnt, tp) - p;
    32   vis[k] = 1;
    33   while (!q.empty()) {
    34     Node u = q.front(); q.pop();
    35     if (u.x == ex && u.y == ey) return u.d;
    36     for (int i = -1; i <= 1; i++) for (int j = -1; j <= 1; j++) if (i != 0 || j != 0) {
    37       int nx = u.x + i, ny = u.y + j;
    38       tp = make_pair(nx, ny);
    39       k = lower_bound(p, p + cnt, tp) - p;
    40       if (p[k] != tp || vis[k]) continue;
    41       vis[k] = 1;
    42       q.push(Node(nx, ny, u.d + 1));
    43     }
    44   }
    45   return -1;
    46 }
    47 
    48 int main() {
    49 //  freopen("case.in", "r", stdin);
    50   while (scanf("%d%d%d%d", &sx, &sy, &ex, &ey) == 4) {
    51     int x;
    52     scanf("%d", &x);
    53     cnt = 0;
    54     for (int i = 0; i < x; i++) {
    55       int r, a, b;
    56       scanf("%d%d%d", &r, &a, &b);
    57       for (int j = a; j <= b; j++)
    58         p[cnt++] = make_pair(r, j);
    59     }
    60     p[cnt++] = make_pair(sx, sy);
    61     p[cnt++] = make_pair(ex, ey);
    62     sort(p, p + cnt);
    63 
    64     printf("%d
    ", bfs());
    65 
    66   }
    67   return 0;
    68 }
    代码君

     

    Problem H 第十四个目标

    题意:略

    题解:dp+离散化用二分即可。

     

    Problem I 中位数

    题意:略

    题解:据说是主席树,然而并不会,先留个坑。

  • 相关阅读:
    看某视频开始做LINUX笔记的第一天
    shell作业01
    学习shell的第一天
    学python的第三天
    【安全】573- 大前端网络安全精简指南手册
    【JS】572- JS 经典实例收集整理
    【Vuejs】571- Vue 虚拟DOM和Diff算法源码解析
    【JS】570- 揭开 JavaScript 引擎的面纱
    【JS】569- 如何避免这4类 JavaScript 内存泄漏?
    【拓展】如何在Gihub上面精准搜索开源项目?
  • 原文地址:https://www.cnblogs.com/zhenhao1/p/5459618.html
Copyright © 2011-2022 走看看