http://acm.hust.edu.cn/vjudge/contest/129783#problem/Fnode
During the next century certain regions on earth will experience severe water shortages. The old town of Uqbar has already started to prepare itself for the worst. Recently they created a network of pipes connecting the cisterns that distribute water in each neighbourhood, making it easier to fill them at once from a single source of water. But in case of water shortage the cisterns above a certain level will be empty since the water will to the cisterns below.
You have been asked to write a program to compute the level to which cisterns will be lled with a certain volume of water, given the dimensions and position of each cistern. To simplify we will neglect the volume of water in the pipes.
Task
Write a program which for each data set:
reads the description of cisterns and the volume of water,
computes the level to which the cisterns will be filled with the given amount of water,
writes the result.
ios
The first line of the input contains the number of data sets k, 1 <= k <= 30. The data sets follow.
The first line of each data set contains one integer n, the number of cisterns, 1 <= n <= 50 000. Each of the following n lines consists of 4 nonnegative integers, separated by single spaces: b, h, w, d - the base level of the cistern, its height, width and depth in meters, respectively. The integers satisfy 0 <= b <= 10^6 and 1 <= h * w * d <= 40 000. The last line of the data set contains an integer V - the volume of water in cubic meters to be injected into the network. Integer V satisfies 1 <= V <= 2 * 10^9.
git
The output should consist of exactly d lines, one line for each data set.
Line i, 1 <= i <= d, should contain the level that the water will reach, in meters, rounded up to two fractional digits, or the word 'OVERFLOW', if the volume of water exceeds the total capacity of the cisterns.
spa
3 2 0 1 1 1 2 1 1 1 1 4 11 7 5 1 15 6 2 2 5 8 5 1 19 4 8 1 132 4 11 7 5 1 15 6 2 2 5 8 5 1 19 4 8 1 78
1.00 OVERFLOW 17.00
2016-HUST-線下組隊賽-3
code
給出n個長方體水箱,從下往上依次注入V升水. 求最後結果的高度.
排序
對長方體的上下底面排序後直接模擬便可,維護當前高度時長方體的截面面積之和. 每次枚舉到下底時把面積加入,枚舉到下底時減去面積.
當枚舉到某個上底時,水不夠注滿到這個高度,那麼用剩餘體積除以當前截面,就是剩下的高度.
還有種作法是二分最終高度,並遍歷全部長方體計算是否可以用.
這道水題成爲了今天的敗筆. 2個多小時才過.
一開始就想的是二分,而後我特地處理都乘了個100來避免浮點數. 結果WA. 應該是由於可能不能剛好用完致使的.
而後改爲double的仍是WA. 後來重寫了一份模擬,仍是WA.
錯點在於,一開始把rounded up錯誤理解成爲向上取整,結果每次輸出我都加了個0.005致使GG.
模擬過了以後覺得二分的精度不夠,這題不能用二分. 回來補題才發現輸出必定只能用 %f , 不能用 %lf. (否者WA,至於精度,各類姿式處理都能過).
double輸出再用%lf就吃鍵盤!!!!!
ip
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <map> #include <set> #include <stack> #include <vector> #include <list> #define LL long long #define eps 1e-8 #define maxn 50010 #define mod 100000007 #define inf 0x3f3f3f3f3f3f3f3f #define mid(a,b) ((a+b)>>1) #define IN freopen("in.txt","r",stdin); using namespace std; int n; LL V; struct node { LL b,h,w,d; }p[maxn]; bool vis[maxn]; typedef pair<LL,int> pii; pii edge[maxn*2]; int main(int argc, char const *argv[]) { //IN; int t; cin >> t; while(t--) { scanf("%d", &n); int cnt = 0; for(int i=1; i<=n; i++) { scanf("%I64d %I64d %I64d %I64d", &p[i].b, &p[i].h, &p[i].w, &p[i].d); edge[++cnt] = make_pair(p[i].b, i); edge[++cnt] = make_pair(p[i].b + p[i].h, i); } scanf("%I64d", &V); sort(edge+1, edge+1+2*n); memset(vis, 0, sizeof(vis)); LL area = 0; LL ans = edge[1].first; double last = inf; for(int i=1; i<=2*n; i++) { LL top = edge[i].first; int num = edge[i].second; if((top-ans)*area >= V) { last = (double)V / (double)area; V = 0; break; } if(vis[num]) { V -= area * (top-ans); area -= p[num].w*p[num].d; ans = top; } else { V -= area * (top-ans); area += p[num].w*p[num].d; vis[num] = 1; ans = top; } } if(V > 0) printf("OVERFLOW\n"); else { printf("%.2f\n", last+(double)ans); } } return 0; }
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <map> #include <set> #include <stack> #include <vector> #include <list> #define LL long long #define eps 1e-8 #define maxn 50010 #define mod 100000007 #define inf 0x3f3f3f3f #define mid(a,b) ((a+b)>>1) #define IN freopen("in.txt","r",stdin); using namespace std; int n; double V; struct node { double b,h,w,d; bool operator < (const node& B) const { return b < B.b; } }p[maxn]; double cal(double dep) { double ret = V; for(int i=1; i<=n && dep>=p[i].b; i++) { if(dep >= p[i].b + p[i].h) ret -= p[i].h * p[i].w * p[i].d; else ret -= (dep - p[i].b) * p[i].w * p[i].d; if(ret < 0) break; } return ret; } int main(int argc, char const *argv[]) { //IN; int t; cin >> t; while(t--) { scanf("%d", &n); double L = inf, R = -inf; for(int i=1; i<=n; i++) { scanf("%lf %lf %lf %lf", &p[i].b, &p[i].h, &p[i].w, &p[i].d); L = min(L, p[i].b); R = max(R, p[i].b + p[i].h); } scanf("%lf", &V); double tmp = V; for(int i=1; i<=n; i++) { tmp -= p[i].h*p[i].w*p[i].d; if(tmp < 0) break; } if(tmp > 0) { printf("OVERFLOW\n"); continue; } sort(p+1, p+1+n); double mid; double ans = inf; while(L <= R) { mid = (L + R) / 2.0; double cur = cal(mid); if(cur <= 0) { if(fabs(cur) < eps) ans = min(ans, mid); R = mid - 0.001; } else L = mid + 0.001; } ans = min(ans, mid); printf("%.2f\n", ans); } return 0; }