こんにちは! mnbd(@mnbbbbbd)です。
プログラミング初心者なので、もっといい回答があるに違いありません。
あくまでも「動作はする」サンプルとしてご覧ください。
問題文
地域の治水対策として、洪水の被害状況をシミュレーションで仮想してみよう。
図のように 1×1(m2)1×1(m2) の区画からなる格子上に表された地域の模式断面図が与えられるので、地域にできる各水たまりの面積を報告してください。
(図はサイトをご覧ください)
与えられた地域に対して限りなく雨が降り、地域から溢れ出た水は左右の海に流れ出ると仮定します。 例えば、図の断面図では、左から面積が 4、2、1、19、9 の水たまりができます。
https://onlinejudge.u-aizu.ac.jp/courses/lesson/1/ALDS1/3/ALDS1_3_D
解答
#include <bits/stdc++.h>
using namespace std;
int main() {
char c;
stack<int> s1;
stack<pair<int, int>> s2;
int index, top, total, area;
string str;
cin >> str;
//string str = "\\\\//";
for(int i = 0; i < str.size(); i++) {
if(str[i] == '\\') {
s1.push(index);
} else if(str[i] == '/' && !s1.empty()) {
top = s1.top();
s1.pop();
area = index - top;
total += area;
while(!s2.empty() && s2.top().first > top) {
area += s2.top().second;
s2.pop();
}
s2.push(make_pair(top, area));
}
index++;
}
cout << total << endl;
vector<int> list;
int s2_size = s2.size();
for(int i = 0; i < s2_size; i++) {
list.push_back(s2.top().second);
s2.pop();
}
cout << list.size();
for(int i = list.size() - 1; i >= 0; i--) {
cout << " " << list.at(i);
}
cout << endl;
return 0;
}
感想
とにかく難しかった!
どのように考えていいのかもわかりませんでした。
他の方の考え方を参考に自分なりに試行錯誤してみたものの、それでもわかりませんでしたね。
はじめてスタックをスタックのサンプルを動かす以外で使ったという感じです。
こういうときにスタックを使うのかと。
それとスタックの中身を表示する場合、配列に読み込んでから逆順で表示する必要がありました。
C++標準のデータ構造の境界値の値にもつまずきました。
こういう問題を自力で解けるようになりたいものです。
まとめ
AIZU ONLINE JUDGEの「ALDS1_3_D Areas on the Cross-Section Diagram」を解いてみましたので、その回答と解説をご紹介いたしました。
少しずつですが、プログラミングの勉強をしています。
まだ初心者ですが、よかったらつながっていただけると嬉しいです。
Twitterアカウント(@mnbbbbbd)
以上です。
読んでいただきありがとうございました!