UVa 11729
cpp
#include <cstdio> #include <cmath> #include <iostream> #include <algorithm> using namespace std; struct Ant { int id; int p; int d; bool operator < (const Ant& a) const { return p < a.p; } }; const int MAXN = 10010; const char dirName[][10] = {"L", "Turning", "R"}; Ant before[MAXN], after[MAXN]; int order[MAXN]; int main(int argc, const char *argv[]) { freopen("input", "r", stdin); int t; int L, T, n; int p, d; char c; scanf("%d", &t); for(int kase = 1; kase <= t; kase++) { printf("Case #%d:\n", kase); scanf("%d%d%d", &L, &T, &n); for(int i = 0; i < n; i++) { scanf("%d %c", &p, &c); d = c == 'L' ? -1 : 1; before[i] = (Ant) {i, p, d}; after[i] = (Ant) {0, p+T*d, d}; } sort(before, before+n); for(int i = 0 ;i < n;i ++) order[before[i].id] = i; sort(after, after+n); for(int i = 0; i < n; i++) if(after[i].p == after[i+1].p) after[i].d = after[i+1].d = 0; for(int i = 0; i <n; i++) { int a = order[i]; if(after[a].p < 0 || after[a].p > L) puts("Fell off"); else printf("%d %s\n", after[a].p, dirName[after[a].d+1]); } printf("\n"); } return 0; } #include <cstdio> #include <cmath> #include <iostream> #include <algorithm> using namespace std; struct Ant { int id; int p; int d; bool operator < (const Ant& a) const { return p < a.p; } }; const int MAXN = 10010; const char dirName[][10] = {"L", "Turning", "R"}; Ant before[MAXN], after[MAXN]; int order[MAXN]; int main(int argc, const char *argv[]) { freopen("input", "r", stdin); int t; int L, T, n; int p, d; char c; scanf("%d", &t); for(int kase = 1; kase <= t; kase++) { printf("Case #%d:\n", kase); scanf("%d%d%d", &L, &T, &n); for(int i = 0; i < n; i++) { scanf("%d %c", &p, &c); d = c == 'L' ? -1 : 1; before[i] = (Ant) {i, p, d}; after[i] = (Ant) {0, p+T*d, d}; } sort(before, before+n); for(int i = 0 ;i < n;i ++) order[before[i].id] = i; sort(after, after+n); for(int i = 0; i < n; i++) if(after[i].p == after[i+1].p) after[i].d = after[i+1].d = 0; for(int i = 0; i <n; i++) { int a = order[i]; if(after[a].p < 0 || after[a].p > L) puts("Fell off"); else printf("%d %s\n", after[a].p, dirName[after[a].d+1]); } printf("\n"); } return 0; }
UVa 11292 勇士斗恶龙
排序,贪心
c
#include <stdio.h> #include <algorithm> using namespace std; int main() { // freopen("input", "r", stdin); const int MAXN = 20010; int dra[MAXN]; int sol[MAXN]; int m, n; while(scanf("%d%d", &n, &m)) { if(n == m && n == 0) break; for(int i = 0; i < n; i++) scanf("%d", &dra[i]); for(int i = 0; i < m; i++) scanf("%d", &sol[i]); sort(dra, dra+n); sort(sol, sol+m); int i, j, cost; i = j = cost = 0; for(;;) { if(i == n || j == m) break; if(dra[i] > sol[j]) j++; else { cost += sol[j]; i++; j++; } } if(i == n) printf("%d\n", cost); else puts("Loowater is doomed!"); } return 0; }
UVa 11300
这个题目很有价值。
一方面通过数学推导得出结论。
编号为i的人初始有$A_i$枚金币。对于1号,给了4号$x_1$枚金币,自己还有$A_1-x_1$枚。然后从2号拿走$x_2$枚金币,现在有$A_1-x_1+x_2$枚金币,另外,设平均金币值为$A_1-x_1+x_2=M$。
由此可类推得到
$A_n-x_n+x_1 \Rightarrow x_n=M-A_n+x_1=x_n-C_n$
我们可以得到类推公式
$$C_i = C_{i-1} + A_i - M $$
证明:
$$x_2 = x_1 - C_1$$
$$x_3 = M-A_2+x_2 =2M-A_1-A_2+x_1=x_1-C_2$$\
以此类推。
可以求得,需要求的结果为:
$$|x_1|+|x_1-C_1|+|x_1-C_2|....|x_1-C_n-1|$$
即求这个式子值最小,即求$C_1, C_2, ...C_n$的中位数。
c
#include <stdio.h> #include <algorithm> #include <math.h> #define lln long long using namespace std; const int MAXN = 1000000 + 10; lln gold[MAXN], C[MAXN]; int main() { // freopen("input", "r", stdin); lln n, sum, per, cnt; while(~scanf("%lld", &n)) { sum = 0; for(int i = 0; i < n; i++) { scanf("%lld", &gold[i]); sum += gold[i]; } per = sum / n; C[0] = 0; for(int i = 0; i < n; i++) C[i] = C[i-1] + gold[i] - per; sort(C, C+n); cnt = 0; lln x1 = C[n/2]; for(int i = 0; i < n; i++) cnt += abs(x1 - C[i]); printf("%lld\n", cnt); } return 0; }
LA 3708
这个题目也是比较有水平
使用了按比例缩小的技巧。其中,按逆时针编号,固定一个点作为原点,建立新坐标。原来的位置呈现在新坐标的位置为$pos = i/n*(n+m)$,如此,求移动距离则是$fabs(pos - floor(pos+0.5))/(n+m)$
c
#include <cstdio> #include <cmath> #include <algorithm> using namespace std; int main() { // freopen("input", "r", stdin); int n, m; double pos, ans; while(scanf("%d%d", &n, &m) != EOF) { ans = 0; for(int i = 1; i < n; i++) { pos = (double)i / n * (n+m); ans += fabs(pos - floor(pos+0.5))/(n+m); } printf("%.4lf\n", ans*10000); } return 0; }
UVa 10881
蓝桥杯去年山东省的初赛题目,的确有点意思= =
转换方向可以不必在意,因为最终看到的结果已经不知道最初的蚂蚁是哪一只了,所以不用纠结方向的问题。主要要考虑的是最终的位置,以及最初蚂蚁位置的存储,before,after的对应关系。
c
#include <cstdio> #include <cmath> #include <iostream> #include <algorithm> using namespace std; struct Ant { int id; int p; int d; bool operator < (const Ant& a) const { return p < a.p; } }; const int MAXN = 10010; const char dirName[][10] = {"L", "Turning", "R"}; Ant before[MAXN], after[MAXN]; int order[MAXN]; int main(int argc, const char *argv[]) { freopen("input", "r", stdin); int t; int L, T, n; int p, d; char c; scanf("%d", &t); for(int kase = 1; kase <= t; kase++) { printf("Case #%d:\n", kase); scanf("%d%d%d", &L, &T, &n); for(int i = 0; i < n; i++) { scanf("%d %c", &p, &c); d = c == 'L' ? -1 : 1; before[i] = (Ant) {i, p, d}; after[i] = (Ant) {0, p+T*d, d}; } sort(before, before+n); for(int i = 0 ;i < n;i ++) order[before[i].id] = i; sort(after, after+n); for(int i = 0; i < n; i++) if(after[i].p == after[i+1].p) after[i].d = after[i+1].d = 0; for(int i = 0; i <n; i++) { int a = order[i]; if(after[a].p < 0 || after[a].p > L) puts("Fell off"); else printf("%d %s\n", after[a].p, dirName[after[a].d+1]); } printf("\n"); } return 0; }
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。