浙江省高职院校联合训练(一)

题目链接:http://acm.hdu.edu.cn/webcontest/contest_show.php?cid=13137

A .Problem A(ZOJ1048普通签到题)

sol:不解释

  • 水题
    #include "cstdio"
    using namespace std;
    int main() {
        double sum = 0, k;
        for (int i = 0; i < 12; i++) {
            scanf("%lf", &k);
            sum += k;
        }
        printf("$%.2lf\n", sum / 12);
        return 0;
    } 
    View Code

     

B .Problem B(POJ2632复杂模拟题)

sol:模拟题解法不一,做着相当恶心人。把昨天的代码理了理重写了一份

  •  恶心人的模拟题
    #include "cstdio"
    #include "string"
    #include "iostream"
    #include "cstring"
    using namespace std;
    const int MAXN = 105;
    struct Robot {
        int x, y, d;
    } rbt[MAXN];
    int n, m;
    string ans;
    int mp[MAXN][MAXN];
    int dir[4][2] = {1, 0, 0, -1, -1, 0, 0, 1};
    // 将方向表示成int,方便转向的时候加减 
    int getDir(char c) {
        switch (c) {
            case 'N' : return 0;
            case 'W' : return 1;
            case 'S' : return 2;
            case 'E' : return 3;
        }
    }
    // 将int转成string 
    string itoa(int k) {
        if (k == 100) {
            return "100";
        }
        string s = "";
        if (k >= 10) {
            s += k / 10 + '0';
            s += k % 10 + '0';
        } else {
            s += k + '0';
        }
        return s;
    }
    // 检查是否越界或者撞上其他机器人 
    bool check(int k, int x, int y) {
        if (x <= 0 || y <= 0 || x > n || y > m) {
            ans = "Robot ";
            ans += itoa(k);
            ans += " crashes into the wall";
            return true;
        }
        if (mp[x][y]) {
            ans = "Robot ";
            ans += itoa(k);
            ans += " crashes into robot ";
            ans += itoa(mp[x][y]);
            return true;
        }
        return false;
    }
    // 移动机器人 
    void move(int k, int d) {
        int xx = dir[rbt[k].d][0], yy = dir[rbt[k].d][1];
        int x = rbt[k].x, y = rbt[k].y;
        mp[x][y] = 0;
        for (int i = 0; i < d; i++) {
            x += xx;
            y += yy;
            if (check(k, x, y)) return;
        }
        mp[x][y] = k;
        rbt[k].x = x;
        rbt[k].y = y;
    }
    // 给机器人转向 
    void changeDir(int k, int d) {
        rbt[k].d = (rbt[k].d + d) % 4;
        if (rbt[k].d < 0) rbt[k].d += 4;
    }
    int main() {
        int t, k1, k2;
        scanf("%d", &t);
        while (t--) {
             scanf("%d%d%d%d", &m, &n, &k1, &k2);
            for (int i = 1; i <= k1; i++) {
                int x, y; char c;
                scanf("%d %d %c", &y, &x, &c);
                rbt[i] = {x, y, getDir(c)};
                mp[x][y] = i;
            }
            ans = "OK";
            for (int i = 1; i <= k2; i++) {
                int id, k; char op;
                scanf("%d %c %d", &id, &op, &k);
                if (ans[0] != 'O') continue;
                if (op == 'F') move(id, k);
                else if (op == 'L') changeDir(id, k % 4);
                else changeDir(id, -k % 4);
            }
            cout << ans << endl;
            memset(mp, 0, sizeof(mp));
        }
        return 0;
    } 
    View Code

     

E .Problem E(ZOJ2371递推、组合数学)

sol:先把n减1,然后从n的二进制低位往高位遍历,如果((1 << k) & n) == 1,就输出数组中的第k + 1个数。注意一下格式并且特判n - 1之后是0的情况还有高精度。

ps:JAVA自带高精度类,所以写大数首选JAVA

  • 高精度,数学
    import java.math.BigInteger;
    import java.util.Scanner;
    
    public class Main {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Scanner sc = new Scanner(System.in);
            long n = sc.nextLong() - 1;
            while (n != -1) {
                if (n == 0) {
                    System.out.println("{ }");
                    n = sc.nextLong() - 1;
                    continue;
                }
                BigInteger pw = BigInteger.ONE;
                System.out.print("{ ");
                while (n != 1) {
                    if ((n & 1) == 1) {
                        System.out.print(pw + ", ");
                    }
                    pw = pw.multiply(new BigInteger("3"));
                    n >>= 1;
                }
                System.out.println(pw + " }");
                n = sc.nextLong() - 1;
            }
        }
    
    }
    View Code

     

F .Problem F(POJ1064二分)

sol:二分答案,判断答案小了或是大了。

ps:用double会造成精度丢失

  • 简单二分
    #include "cstdio"
    using namespace std;
    const int MAXN = 10005;
    int n, m;
    int cable[MAXN];
    bool check(int mid) {
        int sum = 0;
        for (int i = 1; i <= n; i++) 
            sum += cable[i] / mid;
        return sum >= m;
    }
    int main() {
        double k;
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++) {
            scanf("%lf", &k);
            cable[i] = k * 100 + 0.1;
        }
        // 我们要的答案一定在0到1e9; 
        int l = 0, r = 1e9;
        while (r - l > 1) {
            int mid = l + r >> 1;
            if (check(mid)) l = mid;
            else r = mid;
        }
        printf("%d.%02d\n", l / 100, l % 100);
        return 0;
    } 
    View Code

    比赛时间不够,题目都来不及读。看完题发现还是挺简单的

H .Problem H(ZOJ1195简单模拟)

sol:记录每台机器状态和电流,每次转换修改sum,然后和mx比较。

ps: Output a blank line after each test case.

  • 水题
    #include "cstdio"
    #include "cstring"
    #include "algorithm" 
    using namespace std;
    const int MAXN = 25;
    int arr[MAXN];
    bool open[MAXN];
    int main() {
        int n, m, k, q, ca = 1;
        while (scanf("%d%d%d", &n, &m, &k) && (n || m || k)) {
            memset(open, false, sizeof(open));
            int sum = 0, mx = 0;
            for (int i = 1; i <= n; i++)
                scanf("%d", &arr[i]);
            for (int i = 1; i <= m; i++) {
                scanf("%d", &q);
                if (open[q]) {
                    sum -= arr[q];
                } else {
                    sum += arr[q];
                }
                open[q] = !open[q];
                mx = max(mx, sum);
            }
            printf("Sequence %d\n", ca++);
            if (mx <= k) {
                printf("Fuse was not blown.\n");
                printf("Maximal power consumption was %d amperes.\n", mx);
            } else {
                printf("Fuse was blown.\n");
            }
            puts("");
        }
        return 0;
    }
    View Code

     

J .Problem J(ZOJ1195普通签到题)

sol:写一个翻转数字的自定义函数,剩下的就好办了。全写主函数里会有点复杂

  • 水题
    #include "cstdio"
    #include "cstring"
    #include "algorithm" 
    using namespace std;
    int rev(int k) {
        int res = 0;
        while (k) {
            res = res * 10 + k % 10;
            k /= 10;
        }
        return res;
    }
    int main() {
        int t, a, b;
        scanf("%d", &t);
        while (t--) {
            scanf("%d%d", &a, &b);
            printf("%d\n", rev(rev(a) + rev(b)));
        }
        return 0;
    }
    View Code

     

I .Problem I(POJ1877贪心)

sol:sort一下,然后每次都往海拔最低的地方注水。特判k == 0的情况。

ps:让我好好吐槽一下。这题真心坑,建议直接去POJ提交,而且要选择C++编译器不要G++编译器。在HUD上提交一次AC之后再次提交一样的代码就wa了。说好的"The final value in each region description is an integer",integer就这么变成了double。莫名其妙还浪费时间

  • 贪心
    #include "cstdio"
    #include "algorithm"
    using namespace std;
    const int MAXN = 905;
    const int INF = 0x3f3f3f3f;
    double arr[MAXN], k;
    int main() {
        int n, m, ca = 1;
        while (scanf("%d%d", &n, &m) && (n || m)) {
            for (int i = 0; i < n * m; i++) 
                scanf("%lf", &arr[i]);
            sort(arr, arr + n * m);
            // 防越界 
            arr[n * m] = INF;
            scanf("%lf", &k);
            k /= 100;
            printf("Region %d\n", ca++);
            // 特判 
            if (k == 0) {
                printf("Water level is %.2lf meters.\n", arr[0]);
                printf("0.00 percent of the region is under water.\n");
                continue;
            }
            for (int i = 1; i <= n * m; i++) {
                if (i * (arr[i] - arr[i - 1]) >= k) {
                    printf("Water level is %.2lf meters.\n", arr[i - 1] + k / i);
                    printf("%.2lf percent of the region is under water.\n", i * 100.0 / n / m);
                    break;
                } else {
                    k -= i * (arr[i] - arr[i - 1]);
                }
            } 
        }
        return 0;
    }
    View Code

     

K .Problem K(ZOJ1331暴力求解、计数排序)

sol:由于数组中的数最多99,可以用计数排序。

  • 计数排序
    #include "cstdio"
    #include "cstring"
    #include "algorithm" 
    using namespace std;
    const int MAXN = 105;
    int cnt[MAXN];
    int main() {
        int n;
        while (scanf("%d", &n) && ~n) {
            if (n == 0) {
                int sum = 0;
                for (int i = 1; i < 50; i++) {
                    if (cnt[i << 1]) {
                        sum += cnt[i];
                    }
                }
                printf("%d\n", sum);
                memset(cnt, 0, sizeof(cnt));
            } else {
                cnt[n]++;
            }
        }
        return 0;
    }
    View Code

     

posted @ 2019-04-25 20:19  Jathon-cnblogs  阅读(245)  评论(0编辑  收藏  举报