7.19 Multi-University Tranining Contest 1

水了。。。彻底水了。。。线段树都成水题了有木有!!!

ACM路茫茫。。

比赛题解:http://page.renren.com/601081183/note/861865911

 

A题KMP求next数组即可

View Code
 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 
 5 char a[50], b[100002], mapp[50];
 6 int pat[100002];
 7 
 8 void getNext(char s[], int next[])
 9 {
10     int i, j, len = strlen(s);
11     i = 0; j = (len+1)/2;
12     next[0] = -1;
13     while (s[j])
14     {
15         if (i == -1 || s[j] == mapp[s[i]-'a'])
16             ++i, ++j, next[j] = i;
17         else
18             i = next[i];
19     }
20 }
21 
22 int main()
23 {
24     int t;
25     scanf("%d", &t);
26     getchar();
27     while (t--)
28     {
29         gets(a);
30         gets(b);
31         int maxm = 0, info;
32         for (int i = 0; a[i]; i++) {
33             mapp[a[i]-'a'] = 'a'+i;
34         }
35         int len = strlen(b);
36         memset(pat, 0, sizeof(pat));
37         getNext(b, pat);
38 
39         maxm = pat[len];
40         info = len - maxm;
41         int cas = 0;
42         char pend[100002] = {0};
43         for (int i = maxm; i < info; i++)
44             pend[i-maxm] = mapp[b[i]-'a'];
45         printf("%s%s\n", b, pend);
46     }
47     return 0;
48 }

 

B题动态规划,dp[i][j][k]:第i层堆j个木块,中间断不断开的情况总数

View Code
 1 #include <cstdio>
 2 
 3 //DP[i][j][k]表示竖着放第i层,放j个时候,这一层中间分隔不分隔的情况总数
 4 const int mod = 100000007;
 5 int dp[1005][2005][2];
 6 
 7 int main() {
 8     int T, n, k;
 9     scanf("%d", &T);
10     dp[1][1][0] = 1;
11     dp[1][2][1] = 1;
12     for (int i = 2; i <= 1000; i++) {
13         dp[i][1][0] = 1;
14         for (int j = 2; j <= 2 * i; j++) {
15             dp[i][j][0] = (dp[i-1][j-1][0] + dp[i-1][j][0] + dp[i-1][j][1] * 2 + dp[i-1][j-1][1]) % mod;
16             dp[i][j][1] = (dp[i-1][j-2][0] + dp[i-1][j-2][1] + dp[i-1][j][1] + dp[i-1][j-1][0] * 2 + dp[i-1][j-1][1] * 2) % mod;
17         }
18     }
19     while (T--) {
20         scanf("%d%d", &n, &k);
21         printf("%d\n", (dp[n][k][0] + dp[n][k][1]) % mod);
22     }                                                                                            
23     return 0;
24 }

 

C题求移动最短距离,线段树,貌似multiset/树状数组也可以过

View Code
  1 //如果整段查找写起来不方便,不彷分为两边查找
  2 #include <iostream>
  3 using namespace std;
  4 
  5 const int M = 100005;
  6 const int INF = 1 << 29;
  7 struct Node {
  8     int left, right;
  9     int sum;
 10 } node[M * 6];
 11 int step;
 12 int dir; //0:left, 1:right
 13 
 14 inline int abs(int& a) {
 15     return (a < 0) ? -a : a;
 16 }
 17 
 18 void CreateTree(int L, int R, int id) {
 19     node[id].left = L;
 20     node[id].right = R;
 21     node[id].sum = 0;
 22     if (L == R) {
 23         return;
 24     }
 25     int mid = (L + R) / 2;
 26     CreateTree(L, mid, 2 * id);
 27     CreateTree(mid + 1, R, 2 * id + 1);
 28 }
 29 
 30 void Update(int L, int R, int id, int val) {
 31     if (node[id].left == node[id].right) {
 32         node[id].sum += val;
 33         return;
 34     }
 35     int mid = (node[id].left + node[id].right) / 2;
 36     if (R <= mid) {
 37         Update(L, R, 2 * id, val);
 38     } else {
 39         if (L > mid) {
 40             Update(L, R, 2 * id + 1, val);
 41         } else {
 42             Update(L, mid, 2 * id, val);
 43             Update(mid + 1, R, 2 * id + 1, val);
 44         }
 45     }
 46     node[id].sum = node[2 * id].sum + node[2 * id + 1].sum;
 47 }
 48 
 49 int FindLeft(int L, int R, int id) {
 50     if (node[id].sum == 0) {
 51         return INF;
 52     }
 53     if (node[id].left == node[id].right) {
 54         return node[id].left;
 55     }
 56     int mid = (node[id].left + node[id].right) >> 1;
 57     if (R <= mid) {
 58         return FindLeft(L, R, 2 * id);
 59     } else {
 60         if (L > mid) {
 61             return FindLeft(L, R, 2 * id + 1);
 62         } else {
 63             int value = FindLeft(mid + 1, R, 2 * id + 1);
 64             if (value < INF) {
 65                 return value;
 66             }
 67             return FindLeft(L, mid, 2 * id);
 68         }
 69     }
 70 }
 71 
 72 int FindRight(int L, int R, int id) {
 73     if (node[id].sum == 0) {
 74         return INF;
 75     }
 76     if (node[id].left == node[id].right) {
 77         return node[id].left;
 78     }
 79     int mid = (node[id].left + node[id].right) >> 1;
 80     if (R <= mid) {
 81         return FindRight(L, R, 2 * id);
 82     } else {
 83         if (L > mid) {
 84             return FindRight(L, R, 2 * id + 1);
 85         } else {
 86             int value = FindRight(L, mid, 2 * id);
 87             if (value < INF) {
 88                 return value;
 89             }
 90             return FindRight(mid + 1, R, 2 * id + 1);
 91         }
 92     }
 93 }
 94 
 95 int main()
 96 {
 97     int T, cas = 1;
 98     scanf("%d", &T);
 99     while (T--) {
100         int l, n, sum = 0;
101         step = 0;
102         dir = 1;
103         scanf("%d%d", &l, &n);
104         CreateTree(0, l, 1);
105         while (n--) {
106             int s, p;
107             scanf("%d", &s);
108             if (s) {
109                 int tmpl = FindLeft(0, step, 1);
110                 int tmpr = FindRight(step, l, 1);
111                 if (tmpl == INF && tmpr == INF) {
112                     continue;
113                 }
114                 if (abs(tmpl - step) < abs(tmpr - step)) {
115                     sum += abs(tmpl - step);
116                     dir = 0;
117                     step = tmpl;
118                     Update(step, step, 1, -1);
119                 } else if (abs(tmpl - step) > abs(tmpr - step)) {
120                     sum += abs(tmpr - step);
121                     dir = 1;
122                     step = tmpr;
123                     Update(step, step, 1, -1);
124                 } else {
125                     if (dir == 0) {
126                         sum += abs(tmpl - step);
127                         step = tmpl;
128                         Update(step, step, 1, -1);
129                     } else {
130                         sum += abs(tmpr - step);
131                         step = tmpr;
132                         Update(step, step, 1, -1);
133                     }
134                 }
135             } else {
136                 scanf("%d", &p);
137                 Update(p, p, 1, 1);
138             }
139         }
140         printf("Case %d: %d\n", cas++, sum);
141     }
142     return 0;
143 }

 

I题裸BFS

View Code
 1 #include <iostream>
 2 #include <cstring>
 3 #include <queue>
 4 #include <list>
 5 using namespace std;
 6 
 7 struct Point {
 8     int x, y, cost;
 9     bool operator< (const Point& b) const {
10         return cost > b.cost;
11     }
12 } head, tail;
13 list<Point> l;
14 int ans;
15 const int MAXN = 5005;
16 char map[MAXN][MAXN];
17 bool vis[MAXN][MAXN];
18 int r, c, cost, dir[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
19 
20 void bfs() {
21     priority_queue<Point> q;
22     while (!q.empty())
23         q.pop();
24     q.push(head);
25     vis[head.x][head.y] = 1;
26     while (!q.empty()) {
27         Point now = q.top();
28         q.pop();
29         if (now.x == tail.x && now.y == tail.y) {
30             ans = now.cost;
31             break;
32         }
33         for (int i = 0; i < 4; i++) {
34             Point cur = {now.x + dir[i][0], now.y + dir[i][1], now.cost};
35             if (cur.x >= 0 && cur.x < r && cur.y >= 0 && cur.y < c && !vis[cur.x][cur.y] && map[cur.x][cur.y] != '#') {
36                 if (map[cur.x][cur.y] != 'P') {
37                     if (map[cur.x][cur.y] == '*') {
38                         cur.cost += cost;
39                     }
40                     vis[cur.x][cur.y] = 1;
41                     q.push(cur);
42                 } else {
43                     list<Point>::iterator it;
44                     for (it = l.begin(); it != l.end(); it++) {
45                         Point portal = {(*it).x, (*it).y, cur.cost};
46                         vis[portal.x][portal.y] = 1;
47                         q.push(portal);
48                     }
49                 }
50             }
51         }
52     }
53 }
54 
55 int main()
56 {
57     while (~scanf("%d%d%d\n", &r, &c, &cost)) {
58         l.clear();
59         memset(vis, 0, sizeof(vis));
60         ans = 7758258;
61         for (int i = 0; i < r; i++) {
62             gets(map[i]);
63             for (int j = 0; j < c; j++) {
64                 Point cur = {i, j, 0};
65                 if (map[i][j] == 'Y') {
66                     cur.cost = 0;
67                     head = cur;
68                 } else if (map[i][j] == 'C') {
69                     tail = cur;
70                 } else if (map[i][j] == 'P') {
71                     l.push_back(cur);
72                 }
73             }
74         }
75         bfs();
76         if (ans != 7758258) {
77             printf("%d\n", ans);
78         } else {
79             printf("Damn teoy!\n");
80         }
81     }
82     return 0;
83 }

 

就这样,只做出四题。。D题树状DP不会=。=

posted @ 2012-07-22 22:38  dgsrz  阅读(181)  评论(0编辑  收藏  举报