2014百度之星资格赛4题

因为都是中文题。题意就不写了。

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[N][N];
struct CD {
    int t, s;
    void read() {
        scanf("%d%d", &t, &s);
     }
} cd[N];

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[n].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][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;
}
posted @ 2017-07-16 19:37  yangykaifa  阅读(312)  评论(0编辑  收藏  举报