Problem 1133 : Water Tank
http://rose.u-aizu.ac.jp/onlinejudge/ProblemSet/description.jsp?id=1133&lang=jp
Problem 1133 : Water Tank
AOJの問題です。
- 問題概要
水槽の大きさは決まっていて、その中にある仕切りの高さと位置が入力として与えられる。
さらに、蛇口の位置とそこから毎秒でる水の量が与えられる。
指定された時間と位置の水位を出力せよ。
- 解法
仕切られたひとつづつを、容量をもった箱とみなす。
そして、求めたい時間までにでる水をいったんすべていれてしまう。
容量を超えていたらとなりの箱(壁の低い方)に溢れた分をいれる。
溢れようとした先がマンタンの場合は二つの箱を連結し、ひとつの箱とみなす。
- ソース
#include<iostream> #include<algorithm> #include<vector> #include<cstdio> using namespace std; class Tank{ public: int x, w, h1, h2, f, now; bool ad; int capa(){ return w * min(h1, h2) *30; } int next(){ if(h1 > h2){ return 1; } else return -1; } int r(){ return x + w; } bool operator < (const Tank t)const{ return x < t.x; } double height(){ return min((double)50, (double)now/(double)(w*30)); } Tank(){ x = w = h1 = h2 = f = now = 0; ad = false; } void fill(int t){ if(!ad)return; now += t*f; } bool full(){ return now > capa(); } }; main(){ int dataset; cin >> dataset; for(int data=0; data<dataset; data++){ int n; cin >> n; vector<Tank> t(n+1); int prex = 0, preh=50; for(int i=0; i<n; i++){ t[i].x = prex; int tmp; cin >> tmp; t[i].w = tmp - prex; prex = tmp; cin >> t[i].h2; t[i].h1 = preh; preh = t[i].h2; } t[n].x = prex; t[n].w = 100 - prex; t[n].h1 = preh; t[n].h2 = 50; cin >> n; int now=0; for(int i=0; i<n; i++){ int tmp; cin >> tmp; while( t[now].r() < tmp){ now++; } t[now].ad = true; cin >> tmp; t[now].f += tmp; } cin >> n; for(int j=0; j<n; j++){ vector<Tank> v=t; int x, time; cin >> x >> time; for(int i=0; i<v.size(); i++){ v[i].fill(time); } while(1){ bool flg = false; for(int i=0; i<v.size(); i++){ if(v[i].full()){ flg = true; int next = v[i].next() + i; if(v[next].capa() == v[next].now && v[next].next() + next == i){ Tank merge; if(v[i].next() == -1){ merge.h1 = v[next].h1; merge.h2 = v[i].h2; merge.x = v[next].x; } else{ merge.h1 = v[i].h1; merge.h2 = v[next].h2; merge.x = v[i].x; } merge.w = v[i].w + v[next].w; merge.ad = (v[i].ad || v[next].ad); merge.f = v[i].f + v[next].f; merge.now = v[i].now + v[next].now; v.erase(v.begin() + min(next, i)); v.erase(v.begin() + min(next, i)); v.push_back(merge); sort(v.begin(), v.end()); break; } else { v[next].now += (v[i].now - v[i].capa()); v[i].now = v[i].capa(); break; } } } if(!flg){ break; } if(v.size() == 1){ break; } } for(int i=0; i<v.size(); i++){ if(v[i].x< x && x < v[i].r()){ printf("%.5lf\n",v[i].height()); break; } } } } }