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


    题目链接: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
      ", 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
      ", 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
      ", ca++);
              if (mx <= k) {
                  printf("Fuse was not blown.
      ");
                  printf("Maximal power consumption was %d amperes.
      ", mx);
              } else {
                  printf("Fuse was blown.
      ");
              }
              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
      ", 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
      ", ca++);
              // 特判 
              if (k == 0) {
                  printf("Water level is %.2lf meters.
      ", arr[0]);
                  printf("0.00 percent of the region is under water.
      ");
                  continue;
              }
              for (int i = 1; i <= n * m; i++) {
                  if (i * (arr[i] - arr[i - 1]) >= k) {
                      printf("Water level is %.2lf meters.
      ", arr[i - 1] + k / i);
                      printf("%.2lf percent of the region is under water.
      ", 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
      ", sum);
                  memset(cnt, 0, sizeof(cnt));
              } else {
                  cnt[n]++;
              }
          }
          return 0;
      }
      View Code
  • 相关阅读:
    HDU1006
    白话经典算法系列之六 高速排序 高速搞定
    pca算法
    硬件这碗饭有那么好吃吗?
    《学会等待》有感
    oracle execute immediate
    HDU 2059 龟兔赛跑
    C++ Tricks(一)—— 判断字符串 string 对象的所有字符都相等
    辨异 —— 数学基本概念
    辨异 —— 数学基本概念
  • 原文地址:https://www.cnblogs.com/Angel-Demon/p/10766496.html
Copyright © 2020-2023  润新知