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\n", 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\n", 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\n", 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

posted on 2018-06-27 19:50  NineSwords  阅读(176)  评论(0编辑  收藏  举报

导航