先将高度值离散,映射到小范围,然后统计每个高度到下一个高度之间的总容积,最后从下到上不断模拟“填水”的过程。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96 |
#include <stdio.h> #include <algorithm> using
namespace std; const
int maxN = 50001; int n, v; double
lev; int b[2*maxN], h[maxN], w[maxN], d[maxN], cx[2*maxN], cv[2*maxN]; int *p[2*maxN]; void
input(); void
process(); void
compress( int
*, int
*); int
cmp( const
void *sa, const
void *sb); void
print(); int
main() { input(); compress(b, cx); process(); print(); return
0; } void
input() { scanf ( "%d" , &n); for
( int i=1; i<=n; i++) { scanf ( "%d%d%d%d" , &b[i], &h[i], &w[i], &d[i]); b[i+n] = b[i] + h[i]; } b[0] = 0; // 地板 scanf ( "%d" , &v); } void
process() { for
( int i=1; i<=n; i++) { int
t = i + n; int
bt = w[i] * d[i]; for
( int j=b[i]; j<b[t]; j++) { cv[j] += cx[j] * bt; } } for
( int i=0; i<=2*n && v>0; i++) { if
(v>=cv[i]) { v -= cv[i]; lev += cx[i]; } else { lev += v * 1.0 / cv[i] * cx[i]; v = 0; } } } void
compress( int
*x, int
*cx) { for
( int i=0; i<=2*n; i++) p[i] = &x[i]; qsort (p, 2*n+1, sizeof ( int *), cmp); int
t = 0, pt = *p[0]; *p[0] = t; for
( int i=1; i<=2*n; i++) { if
((*p[i])!=pt) { t++; cx[t-1] = *p[i] - pt; } pt = *p[i]; *p[i] = t; } } int
cmp( const
void *sa, const
void *sb) { int
a = **( int **)sa; int
b = **( int **)sb; if
(a>b) return
1; else
return -1; } void
print() { if
(v>0) printf ( "OVERFLOW\n" ); else
printf ( "%.2lf\n" , lev); } |
原文:http://www.cnblogs.com/dgzxoi/p/3562113.html