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不会=。=