2014百度之星资格赛4题
2014-05-24 10:21
288 查看
由于都是中文题,题意就不写了。
这题先判断一下能量是否能增加,然后再根据增加这个公式去求出一个等比公式,就可以直接求出需要增加几次了
首先轨道转移和读取数据时间肯定是要花进去的,剩下就是看转的那部分时间,从0,0开始,回到0,0,中间经过n个点,转化为经典的双调欧几里得DP,就可以求出答案了
从高位建字典树,然后贪心,尽量选择0,1不同的位置去放
很常见的动态规划,dp[i][j][k]代表在(i, j)这个点,从k方向来的状态,然后随便搞搞记忆化搜索
代码:
A、Energy Conversion
这题先判断一下能量是否能增加,然后再根据增加这个公式去求出一个等比公式,就可以直接求出需要增加几次了
B、Disk Schedule
首先轨道转移和读取数据时间肯定是要花进去的,剩下就是看转的那部分时间,从0,0开始,回到0,0,中间经过n个点,转化为经典的双调欧几里得DP,就可以求出答案了
C、Xor Sum
从高位建字典树,然后贪心,尽量选择0,1不同的位置去放
D、Labyrinth
很常见的动态规划,dp[i][j][k]代表在(i, j)这个点,从k方向来的状态,然后随便搞搞记忆化搜索代码:
A:
#include <stdio.h> #include <string.h> #include <math.h> const double eps = 1e-9; int t; double n, m, v, k; int main() { scanf("%d", &t); while (t--) { scanf("%lf%lf%lf%lf", &n, &m, &v, &k); long long ans; if (m >= n) {printf("0\n"); continue;} if ((m - v) * k > m) ans = (long long)(ceil(log((n + v * k / (1 - k)) / (m + v * k / (1 - k))) / log(k)) + eps); else ans = -1; printf("%lld\n", ans); } return 0; }
B:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int N = 1005; int t, n, dp ; struct CD { int t, s; void read() { scanf("%d%d", &t, &s); } } cd ; int dis(int i, int j) { int a = cd[i].s, b = cd[j].s; return min((a - b + 360) % 360, (b - a + 360) % 360); } const int INF = 0x3f3f3f3f; int main() { scanf("%d", &t); while (t--) { scanf("%d", &n); cd[1].t = 0; cd[1].s = 0; int ans = n * 10; n++; for (int i = 2; i <= n; i++) cd[i].read(); ans += cd .t * 800; int an = INF; dp[2][1] = dis(2, 1); for (int i = 3; i <= n; i++) { dp[i][i - 1] = INF; for (int j = 1; j < i - 1; j++) { dp[i][j] = dp[i - 1][j] + dis(i, i - 1); dp[i][i - 1] = min(dp[i][i - 1], dp[i - 1][j] + dis(j, i)); if (i == n) an = min(an, dp[i][j] + dis(j, i)); } } printf("%d\n", ans + min(an, dp [n - 1] + dis(n - 1, n))); } return 0; }
C:
#include <stdio.h> #include <string.h> #include <iostream> using namespace std; int t, n, m, ans[105], an, rtn; __int64 num, mi[50]; struct Tree { int value; int left, right; void init() { value = 0; left = -1; right = -1; } Tree(){} Tree(int v, int l, int r) { value = v; left = l; right = r; } } root[5000005]; void insert(Tree &roo, __int64 num, int d) { if (d == 0) return; __int64 t = 0; if (num >= mi[d - 1]) { num -= mi[d - 1]; t = 1; } if (t == 0) { if (roo.left == -1) { roo.left = ++rtn; root[roo.left] = Tree(0, -1, -1); } insert(root[roo.left], num, d - 1); } else { if (roo.right == -1) { roo.right = ++rtn; root[roo.right] = Tree(1, -1, -1); } insert(root[roo.right], num, d - 1); } } void find(Tree roo, __int64 num, int d) { if (d == 0) return; __int64 t = 0; if (num >= mi[d - 1]) { num -= mi[d - 1]; t = 1; } if (t == 0) { if (roo.right == -1) { find(root[roo.left], num, d - 1); ans[d - 1] = 0; } else { ans[d - 1] = 1; find(root[roo.right], num, d - 1); } } else { if (roo.left == -1) { ans[d - 1] = 1; find(root[roo.right], num, d - 1); } else { ans[d - 1] = 0; find(root[roo.left], num, d - 1); } } } int main() { mi[0] = 1; for (int i = 1; i <= 50; i++) mi[i] = mi[i - 1] * 2; int cas = 0; scanf("%d", &t); while (t--) { rtn = 0; root[0] = Tree(0, -1, -1); scanf("%d%d", &n, &m); while (n--) { scanf("%I64d", &num); insert(root[0], num, 50); } printf("Case #%d:\n", ++cas); while (m--) { scanf("%I64d", &num); find(root[0], num, 50); __int64 out = 0; for (int i = 50; i >= 0; i--) out = out * 2 + ans[i]; printf("%I64d\n", out); } } return 0; }
D:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int INF = 0x3f3f3f3f; int t, n, m, g[105][105], vis[105][105][3], dp[105][105][3]; const int d[3][2] = {1, 0, -1, 0, 0, 1}; int dfs(int x, int y, int v) { int &ans = dp[x][y][v]; if (vis[x][y][v]) return ans; vis[x][y][v] = 1; ans = -INF; if (x == 0 && y == m - 1) { return ans = g[x][y]; } for (int i = 0; i < 3; i++) { if ((v == 0 && i == 1) || (v == 1 && i == 0)) continue; int xx = x + d[i][0]; int yy = y + d[i][1]; if (xx < 0 || xx >= n || yy < 0 || yy >= m) continue; ans = max(ans, dfs(xx, yy, i) + g[x][y]); } return ans; } int main() { scanf("%d", &t); int cas = 0; while (t--) { memset(vis, 0, sizeof(vis)); scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) scanf("%d", &g[i][j]); printf("Case #%d:\n", ++cas); printf("%d\n", dfs(0, 0, 0)); } return 0; }
相关文章推荐
- 2014百度之星资格赛4题
- 2014百度之星资格赛4题
- 2014百度之星资格赛 1001-Energy Conversion
- 2014 百度之星 资格赛 Labyrinth
- 2014百度之星资格赛第四题
- 2014百度之星资格赛 1004:Labyrinth(DP)
- 2014百度之星资格赛—— Xor Sum(01字典树)
- 2014百度之星资格赛第四题
- 2014百度之星资格赛解题报告:Disk Schedule
- 2014百度之星资格赛题目解析
- 2014在百度之星资格赛的第四个冠军Labyrinth
- 2014百度之星资格赛1004
- 2014百度之星资格赛第一道Energy Conversion
- 2014百度之星资格赛——Labyrinth
- 2014百度之星资格赛解题报告:Disk Schedule
- [百度之星2014资格赛] Disk Schedule 报告
- 2014百度之星资格赛——Disk Schedule
- 2014在百度之星资格赛的第二个问题Disk Schedule
- 2014百度之星资格赛1004 度度熊走迷宫 Labyrinth
- 百度之星2014资格赛 1004 - Labyrinth