题目链接: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; }
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; }
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; } } }
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; }
比赛时间不够,题目都来不及读。看完题发现还是挺简单的
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; }
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; }
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; }
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; }