【 2013 Multi-University Training Contest 8 】

HDU 4678 Mine

对于每个空白区域,求SG值。

最后异或起来等于0,先手必败。

  1 #pragma comment(linker,"/STACK:102400000,102400000")
  2 #include<cstdio>
  3 #include<cstring>
  4 #define MAXN 1010
  5 #define oo 1234567890
  6 int arr[MAXN][MAXN];
  7 bool vis[MAXN][MAXN];
  8 int n, m;
  9 int dg, bk;
 10 int sg[MAXN * MAXN][2];
 11 int go[8][2] = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 }, { -1, -1 },
 12         { -1, 1 }, { 1, -1 }, { 1, 1 } };
 13 bool isIn(int x, int y) {
 14     return x >= 0 && x < n && y >= 0 && y < m;
 15 }
 16 int SG(int digit, int blank) {
 17     if (sg[digit][blank] == -1) {
 18         int x, y;
 19         x = y = -1;
 20         if (blank) {
 21             x = SG(0, 0);
 22         }
 23         if (digit) {
 24             y = SG(digit - 1, blank);
 25         }
 26         for (int i = 0;; i++) {
 27             if (i != x && i != y) {
 28                 sg[digit][blank] = i;
 29                 break;
 30             }
 31         }
 32     }
 33     return sg[digit][blank];
 34 }
 35 void dfs(int x, int y) {
 36     vis[x][y] = true;
 37     if (arr[x][y] > 0) {
 38         dg++;
 39     } else if (arr[x][y] == 0) {
 40         bk = 1;
 41         int nx, ny;
 42         for (int i = 0; i < 8; i++) {
 43             nx = x + go[i][0];
 44             ny = y + go[i][1];
 45             if (isIn(nx, ny) && !vis[nx][ny]) {
 46                 dfs(nx, ny);
 47             }
 48         }
 49     }
 50 }
 51 int main() {
 52     int T;
 53     int ca = 1;
 54     int x, y;
 55     int i, j, k;
 56     int res;
 57     memset(sg, -1, sizeof(sg));
 58     sg[0][0] = 0;
 59     scanf("%d", &T);
 60     while (T--) {
 61         scanf("%d%d%d", &n, &m, &k);
 62         memset(arr, 0, sizeof(arr));
 63         while (k--) {
 64             scanf("%d%d", &x, &y);
 65             arr[x][y] = -oo;
 66         }
 67         for (i = 0; i < n; i++) {
 68             for (j = 0; j < m; j++) {
 69                 if (arr[i][j] < 0) {
 70                     for (k = 0; k < 8; k++) {
 71                         x = i + go[k][0];
 72                         y = j + go[k][1];
 73                         if (isIn(x, y)) {
 74                             arr[x][y]++;
 75                         }
 76                     }
 77                 }
 78             }
 79         }
 80         res = 0;
 81         memset(vis, false, sizeof(vis));
 82         for (i = 0; i < n; i++) {
 83             for (j = 0; j < m; j++) {
 84                 if (!vis[i][j] && arr[i][j] == 0) {
 85                     dg = bk = 0;
 86                     dfs(i, j);
 87                     res ^= SG(dg, bk);
 88                 }
 89             }
 90         }
 91         for (i = 0; i < n; i++) {
 92             for (j = 0; j < m; j++) {
 93                 if (!vis[i][j]) {
 94                     dg = bk = 0;
 95                     dfs(i, j);
 96                     res ^= SG(dg, bk);
 97                 }
 98             }
 99         }
100         if (res) {
101             printf("Case #%d: Xiemao
", ca++);
102         } else {
103             printf("Case #%d: Fanglaoshi
", ca++);
104         }
105     }
106     return 0;
107 }
View Code

HDU 4679 Terrorist’s destroy

dp[i][0]表示i为根的最长链。

dp[i][1]表示i为根的次长链。

dp[i][2]表示i为根的第三长链。

  1 #pragma comment(linker,"/STACK:102400000,102400000")
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #define MAXN 200010
  6 #define oo 0x7FFFFFFF
  7 using namespace std;
  8 int first[MAXN], next[MAXN], v[MAXN], cost[MAXN], id[MAXN], e;
  9 int dp[MAXN][3];
 10 bool vis[MAXN];
 11 int res, idx;
 12 void addEdge(int x, int y, int val, int idx) {
 13     cost[e] = val;
 14     id[e] = idx;
 15     v[e] = y;
 16     next[e] = first[x];
 17     first[x] = e++;
 18 }
 19 void dfs(int x) {
 20     vis[x] = true;
 21     dp[x][0] = dp[x][1] = dp[x][2] = 0;
 22     for (int i = first[x]; i != -1; i = next[i]) {
 23         int y = v[i];
 24         if (!vis[y]) {
 25             dfs(y);
 26             if (dp[y][0] + 1 >= dp[x][0]) {
 27                 dp[x][2] = dp[x][1];
 28                 dp[x][1] = dp[x][0];
 29                 dp[x][0] = dp[y][0] + 1;
 30             } else if (dp[y][0] + 1 >= dp[x][1]) {
 31                 dp[x][2] = dp[x][1];
 32                 dp[x][1] = dp[y][0] + 1;
 33             } else if (dp[y][0] + 1 > dp[x][2]) {
 34                 dp[x][2] = dp[y][0] + 1;
 35             }
 36         }
 37     }
 38 }
 39 void search(int x, int pre) {
 40     int tmp;
 41     vis[x] = true;
 42     if (pre != -1) {
 43         if (dp[x][0] + 1 == dp[pre][0]) {
 44             if (dp[pre][1] + 1 >= dp[x][0]) {
 45                 dp[x][2] = dp[x][1];
 46                 dp[x][1] = dp[x][0];
 47                 dp[x][0] = dp[pre][1] + 1;
 48             } else if (dp[pre][1] + 1 >= dp[x][1]) {
 49                 dp[x][2] = dp[x][1];
 50                 dp[x][1] = dp[pre][1] + 1;
 51             } else if (dp[pre][1] + 1 > dp[x][2]) {
 52                 dp[x][2] = dp[pre][1] + 1;
 53             }
 54         } else {
 55             if (dp[pre][0] + 1 >= dp[x][0]) {
 56                 dp[x][2] = dp[x][1];
 57                 dp[x][1] = dp[x][0];
 58                 dp[x][0] = dp[pre][0] + 1;
 59             } else if (dp[pre][0] + 1 >= dp[x][1]) {
 60                 dp[x][2] = dp[x][1];
 61                 dp[x][1] = dp[pre][0] + 1;
 62             } else if (dp[pre][0] + 1 > dp[x][2]) {
 63                 dp[x][2] = dp[pre][0] + 1;
 64             }
 65         }
 66     }
 67     for (int i = first[x]; i != -1; i = next[i]) {
 68         int y = v[i];
 69         if (!vis[y]) {
 70             if (dp[y][0] + 1 == dp[x][0]) {
 71                 tmp = dp[x][1] + dp[x][2];
 72             } else {
 73                 tmp = dp[x][0];
 74                 if (dp[y][0] + 1 == dp[x][1]) {
 75                     tmp += dp[x][2];
 76                 } else {
 77                     tmp += dp[x][1];
 78                 }
 79             }
 80             tmp = cost[i] * max(dp[y][0] + dp[y][1], tmp);
 81             if (tmp < res) {
 82                 res = tmp;
 83                 idx = id[i];
 84             } else if (tmp == res && idx > id[i]) {
 85                 idx = id[i];
 86             }
 87             search(y, x);
 88         }
 89     }
 90 }
 91 int main() {
 92     int T;
 93     int ca = 1;
 94     int n;
 95     int i;
 96     int x, y, val;
 97     scanf("%d", &T);
 98     while (T--) {
 99         scanf("%d", &n);
100         e = 0;
101         memset(first, -1, sizeof(first));
102         for (i = 1; i < n; i++) {
103             scanf("%d%d%d", &x, &y, &val);
104             addEdge(x, y, val, i);
105             addEdge(y, x, val, i);
106         }
107         res = oo;
108         memset(vis, false, sizeof(vis));
109         dfs(1);
110         memset(vis, false, sizeof(vis));
111         search(1, -1);
112         printf("Case #%d: %d
", ca++, idx);
113     }
114     return 0;
115 }
View Code

 

HDU 4681 String

分别枚举D在A和B中的起点,可以暴力得到最短终点。

枚举任意两个起点与终点,通过dp可以求得两端的LCS。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<vector>
 4 #define MAXN 1010
 5 using namespace std;
 6 char a[MAXN], b[MAXN], c[MAXN];
 7 vector<pair<int, int> > p1, p2;
 8 int f[MAXN][MAXN], g[MAXN][MAXN];
 9 void cal(char a[], char c[], vector<pair<int, int> >&p) {
10     int i, j, k;
11     int la = strlen(a + 1);
12     int lc = strlen(c + 1);
13     p.clear();
14     for (i = 1; i <= la; i++) {
15         k = 1;
16         if (a[i] != c[k]) {
17             continue;
18         }
19         for (j = i; j <= la; j++) {
20             if (a[j] == c[k]) {
21                 k++;
22             }
23             if (k > lc) {
24                 break;
25             }
26         }
27         if (k > lc) {
28             p.push_back(make_pair(i, j));
29         }
30     }
31 }
32 int main() {
33     int T;
34     int ca = 1;
35     int ans;
36     int i, j;
37     int la, lb, lc;
38     scanf("%d", &T);
39     while (T--) {
40         scanf(" %s %s %s", a + 1, b + 1, c + 1);
41         la = strlen(a + 1);
42         lb = strlen(b + 1);
43         lc = strlen(c + 1);
44         cal(a, c, p1);
45         cal(b, c, p2);
46         ans = 0;
47         if (!(p1.empty() || p2.empty())) {
48             memset(f, 0, sizeof(f));
49             memset(g, 0, sizeof(g));
50             for (i = 1; i <= la; i++) {
51                 for (j = 1; j <= lb; j++) {
52                     if (a[i] == b[j]) {
53                         f[i][j] = f[i - 1][j - 1] + 1;
54                     } else {
55                         f[i][j] = max(f[i - 1][j], f[i][j - 1]);
56                     }
57                 }
58             }
59             for (i = la; i > 0; i--) {
60                 for (j = lb; j > 0; j--) {
61                     if (a[i] == b[j]) {
62                         g[i][j] = g[i + 1][j + 1] + 1;
63                     } else {
64                         g[i][j] = max(g[i + 1][j], g[i][j + 1]);
65                     }
66                 }
67             }
68             for (i = 0; i < (int) p1.size(); i++) {
69                 for (j = 0; j < (int) p2.size(); j++) {
70                     ans = max(ans,
71                             lc + f[p1[i].first - 1][p2[j].first - 1]
72                                     + g[p1[i].second + 1][p2[j].second + 1]);
73                 }
74             }
75         }
76         printf("Case #%d: %d
", ca++, ans);
77     }
78     return 0;
79 }
View Code

原文地址:https://www.cnblogs.com/DrunBee/p/3260363.html