Areas on the Cross-Section Diagram
Areas on the Cross-Section Diagram Aizu - ALDS1_3_D
Areas on the Cross-Section Diagram
地域の治水対策として、洪水の被害状況をシミュレーションで仮想してみよう。
図のように $1 \times 1 (m^2)$ の区画からなる格子上に表された地域の模式断面図が与えられるので、地域にできる各水たまりの面積を報告してください。
与えられた地域に対して限りなく雨が降り、地域から溢れ出た水は左右の海に流れ出ると仮定します。 例えば、図の断面図では、左から面積が 4、2、1、19、9 の水たまりができます。
入力
模式断面図における斜面を '/' と '\'、平地を '_' で表した文字列が1行に与えられます。例えば、図の模式断面図は文字列 \\///\_/\/\\\\/_/\\///__\\\_\\/_\/_/\ で与えられます。
出力
次の形式で水たまりの面積を出力してください。
$A$
$k$ $L_1$ $L_2$ ... $L_k$
1行目に地域にできる水たまりの総面積を表す整数 $A$ を出力してください。
2行目に水たまりの数 $k$、各水たまりの面積 $L_i (i = 1, 2, ..., k)$ を断面図の左から順番に空白区切りで出力してください。
制約
- $1 \leq 文字列の長さ \leq 20,000$
ただし、得点の 50 点分は以下の条件を満たす。
- 水たまりの数は1つ以下であり ($k \leq 1$)、かつ文字列の長さは 100 以下である。
入力例 1
\\//
出力例 1
4 1 4
入力例 2
\\///\_/\/\\\\/_/\\///__\\\_\\/_\/_/\
出力例 2
35 5 4 2 1 19 9
Note
题目分析:
本题是一道对栈的应用比较好的一道题,不仅运用栈的特性解决了水坑的左右匹配问题,还将他们分开储存,也仅仅只是运用一个下标判断和栈的特性。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <stack> 4 #include <vector> 5 #include <algorithm> 6 using namespace std; 7 8 int main(){ 9 stack<int> S1; 10 stack<pair<int, int> > S2; 11 char ch; 12 int sum = 0; 13 for(int i = 1;cin >> ch; i++){ 14 if(ch == '\\')S1.push(i); 15 else if(ch == '/' && S1.size() > 0){ 16 int j = S1.top();S1.pop(); 17 sum += i - j; 18 int a = i - j; 19 while(S2.size() > 0 && S2.top().first > j){ 20 a += S2.top().second;S2.pop(); 21 } 22 S2.push(make_pair(j, a)); 23 } 24 } 25 vector<int> ans; 26 while(S2.size() > 0){ans.push_back(S2.top().second);S2.pop();} 27 reverse(ans.begin(),ans.end()); 28 cout<< sum << endl; 29 cout<< ans.size(); 30 for( int i = 0; i < ans.size(); i++){ 31 cout<< " "; 32 cout<< ans[i]; 33 } 34 cout << endl; 35 return 0; 36 }