• 2012 Multi-University Training Contest 7


    2012 Multi-University Training Contest 7

    A.As long as Binbin loves Sangsang

    B.Dead or alive

    C.Dragon Ball

    题意:在连续的n秒中,每秒会出现m个龙珠。已知初始位置,每从一个位置i,移动到另一个位置j的时候,消耗的代价为abs(i-j), 知道了每次出现的龙珠的位置及取它的代价,每一秒必须取一颗龙珠。问 n 秒之后花费的最小代价是多少。

    SOL:用dp[i][j]表示i秒之后,留在第j个龙珠所在位置的最小花费,这样就有了一个$O(n*m^2)$的做法,之后很容易想到用单调队列优化,复杂度$O(n*m)$。

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <algorithm>
     6 using namespace std;
     7 const int oo = 1e9;
     8 int i, j, k, n, m, s, t, ans, x;
     9 struct node {
    10     int pos, cost;
    11 } a[55][1005];
    12 int dp[55][1005];
    13 bool cmp(const node &x, const node &y) {
    14     return x.pos < y.pos;
    15 }
    16 int main() {
    17     int T;
    18     scanf("%d", &T);
    19     while (T--) {
    20         scanf("%d %d %d", &n, &m, &x);
    21         for (int i = 1; i <= n; i++) {
    22             for (int j = 1; j <= m; j++) {
    23                 scanf("%d", &a[i][j].pos);
    24             }
    25         }
    26         for (int i = 1; i <= n; i++) {
    27             for (int j = 1; j <= m; j++) {
    28                 scanf("%d", &a[i][j].cost);
    29             }
    30         }
    31         for (int i = 1; i <= n; i++) {
    32             sort(a[i] + 1, a[i] + 1 + m, cmp);
    33         }
    34         for (int j = 1; j <= m; j++) {
    35             dp[1][j] = a[1][j].cost + abs(a[1][j].pos - x);
    36         }
    37         for (int i = 2; i <= n; i++) {
    38             int k = 0, t = oo;
    39             for (int j = 1; j <= m; j++) {
    40                 while (k + 1 <= m && a[i][j].pos >= a[i - 1][k + 1].pos) {
    41                     k++;
    42                     t = min(t, dp[i - 1][k] - a[i - 1][k].pos);
    43                 }
    44                 dp[i][j] = t + a[i][j].cost + a[i][j].pos;
    45             }
    46             k = m + 1, t = oo;
    47             for (int j = m; j >= 1; j--) {
    48                 while (k - 1 >= 1 && a[i][j].pos <= a[i - 1][k - 1].pos) {
    49                     k--;
    50                     t = min(t, dp[i - 1][k] + a[i - 1][k].pos);
    51                 }
    52                 dp[i][j] = min(dp[i][j], t + a[i][j].cost - a[i][j].pos);
    53             }
    54         }
    55         ans = oo;
    56         for (int j = 1; j <= m; j++) {
    57             ans = min(ans, dp[n][j]);
    58         }
    59         printf("%d
    ", ans);
    60     }
    61     return 0;
    62 }
    View Code

    D.Draw and paint

    E.Matrix operation

    F.Palindrome graph

    题意:给你n*n的方格纸,在格子里填颜色,要满足任意水平、垂直翻转,转任意个90度后看到的图形都一样;现在你有k种颜色,有m个格子已经图了颜色,求方案数。

    SOL:直接搞出等价类再用快速幂做一做就好了。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 typedef long long ll;
     7 const int mod  = 100000007;
     8 const int LEN = 1e5 + 5;
     9 int i, j, k, n, m, s, t, ans, tot;
    10 int a[LEN];
    11 int pow_mod(const int &x, int y) {
    12     if (y == 0) {
    13         return 1;
    14     }
    15     int ans = pow_mod(x, y >> 1);
    16     ans = (ll)ans * ans % mod;
    17     if (y & 1) {
    18         ans = (ll)ans * x % mod;
    19     }
    20     return ans;
    21 }
    22 int trans(int x, int y) {
    23     if (x > n / 2) {
    24         x = n + 1 - x;
    25     }
    26     if (y > n / 2) {
    27         y = n + 1 - y;
    28     }
    29     if (x > y) {
    30         swap(x, y);
    31     }
    32     return x * 10000 + y;
    33 }
    34 int getnum(int n) {
    35     int L = (n + 1) / 2;
    36     return (L + 1) * L / 2;
    37 }
    38 int main() {
    39     while (scanf("%d %d %d", &n, &m, &k) != EOF) {
    40         tot = 0;
    41         for (int i = 1; i <= m; i++) {
    42             int x, y;
    43             scanf("%d %d", &x, &y);
    44             x++, y++;
    45             a[++tot] = trans(x, y);
    46         }
    47         if (tot > 0) {
    48             sort(a + 1, a + 1 + tot);
    49             tot = unique(a + 1, a + 1 + tot) - a - 1;
    50         }
    51         printf("%d
    ", pow_mod(k, getnum(n) - tot));
    52     }
    53     return 0;
    54 }
    View Code

    G.Successor

    题意:给你一棵树,每个结点有两个属性值,1.能力值,2.忠诚度。然后m个询问,每次询问一个整数u,求u的子树中能力值大于u的且忠诚度最大的点的编号。

    SOL:先按能力值排序,这样从大到小考虑就满足了条件1,然后从大到小依次在线段树里查询子树中忠诚度最大的点的编号,复杂度O(nlogn)。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #define tl (p << 1)
      6 #define tr (p << 1 | 1)
      7 using namespace std;
      8 const int LEN = 1e5 + 5;
      9 int i, j, k, n, m, s, t, tot, Time;
     10 struct edge {
     11     int vet, next;
     12 } E[LEN * 2];
     13 struct node {
     14     int x, y, id;
     15 } a[LEN];
     16 bool cmp(const node &x, const node &y) {
     17     return x.x > y.x;
     18 };
     19 int head[LEN], size[LEN], tid[LEN], ans[LEN], pre[LEN], b[LEN];
     20 int to[1000005];
     21 int tmax[LEN * 4];
     22 void add(int u, int v) {
     23     E[++tot] = (edge){v, head[u]};
     24     head[u] = tot;
     25 }
     26 void dfs(int u) {
     27     size[u] = 1;
     28     tid[u] = ++Time;
     29     pre[Time] = u;
     30     for (int e = head[u]; e != -1; e = E[e].next) {
     31         int v = E[e].vet;
     32         dfs(v);
     33         size[u] += size[v];
     34     }
     35 }
     36 int ask(int l, int r, int x, int y, int p) {
     37     if (l == x && y == r) {
     38         return tmax[p];
     39     }
     40     int mid = (l + r) >> 1;
     41     if (mid >= y) {
     42         return ask(l, mid, x, y, tl);
     43     } else if (mid + 1 <= x) {
     44         return ask(mid + 1, r, x, y, tr);
     45     } else {
     46         return max(ask(l, mid, x, mid, tl), ask(mid + 1, r, mid + 1, y, tr));
     47     }
     48 }
     49 void update(int p) {
     50     tmax[p] = max(tmax[tl], tmax[tr]);
     51 }
     52 void modify(int l, int r, const int &x, int p, const int &c) {
     53     if (l == r) {
     54         tmax[p] = c;
     55         return;
     56     }
     57     int mid = (l + r) >> 1;
     58     if (mid >= x) {
     59         modify(l, mid, x, tl, c);
     60     } else {
     61         modify(mid + 1, r, x, tr, c);
     62     }
     63     update(p);
     64 }
     65 void build(int l, int r, int p) {
     66     if (l == r) {
     67         tmax[p] = -1;
     68         return;
     69     }
     70     int mid = (l + r) >> 1;
     71     build(l, mid, tl);
     72     build(mid + 1, r, tr);
     73     update(p);
     74 }
     75 int main() {
     76     int T;
     77     scanf("%d", &T);
     78     while (T--) {
     79         tot = Time = 0;
     80         scanf("%d %d", &n, &m);
     81         for (int i = 1; i <= n; i++) {
     82             head[i] = -1;
     83             size[i] = 0;
     84             tid[i] = 0;
     85         }
     86         a[1] = (node){1e9, 0, 1};
     87         for (int i = 2; i <= n; i++) {
     88             int fa, x, y;
     89             scanf("%d %d %d", &fa, &x, &y);
     90             x++,y++,fa++;
     91             swap(x, y);
     92             add(fa, i);
     93             a[i] = (node){x, y, i};
     94             to[y] = i;
     95         }
     96         dfs(1);
     97         build(1, n, 1);
     98         sort(a + 1, a + 1 + n, cmp);
     99         int j = 1;
    100         for (int i = 2; i <= n; i++) {
    101             int x = a[i].id, t = ask(1, n, tid[x], tid[x] + size[x] - 1, 1);
    102             if (t == -1) {
    103                 ans[x] = 0;
    104             } else {
    105                 ans[x] = to[t];
    106             }
    107             while (j + 1 <= i && a[j + 1].x > a[i + 1].x) {
    108                 modify(1, n, tid[a[j + 1].id], 1, a[j + 1].y);
    109                 j++;
    110             }
    111         }
    112         while (m--) {
    113             int x;
    114             scanf("%d", &x);
    115             printf("%d
    ", ans[x + 1] - 1);
    116         }
    117     }
    118     return 0;
    119 }
    View Code

    H.The war of virtual world

    I.Water World I

    J.Water World II

  • 相关阅读:
    Linux 文件隐藏属性-创建文件默认权限
    Linux 文件权限管理
    Linux 用户管理_用户相关配置文件详解
    Linux 压缩包管理
    vim 编辑器高级用法
    Linux ll查看文件属性详解-软硬链接详解
    安卓学习28
    安卓学习27
    安卓学习26
    安卓学习25
  • 原文地址:https://www.cnblogs.com/NineSwords/p/9235738.html
Copyright © 2020-2023  润新知