AIZU ONLINE JUDGE

AOJ ALDS1 3_D(Areas on the Cross-Section Diagram)を解く

AOJ_ALDS1_3_D

Aizu Online Judge(AOJ)が提供している「アルゴリズムとデータ構造入門」(ALDS1)の3_D問題をC++で解いてみました。

ALDS1では、「アルゴリズムとデータ構造の基礎を体得します。」とあります。トピック#3「基本データ構造」では、スタック、キュー、リストを学びます。

問題(3_D: Areas on the Cross-Section Diagram)

問題はリンク先をご覧ください。

AOJ ALDS1 3_D問題: Areas on the Cross-Section Diagram

スタックを用いる応用問題を紹介します。

リストについて

トピック#3の問題として、応用問題を解いてみます。

問題で、以下の地形が与えられます。その地形から水たまりの面積を求めていきます(画像は、問題から借用しました)。

問題 3_A で学んだスタックを使って解きます。

C++ プログラム例(ALDS1 3_D)

水たまりの総面積を変数 sum で、各水たまりの量を配列 result に格納します。スタックは以下の2つを用意します。

  • スタック pos は、右下がりの位置をpushしておきます。右上がりを検出した場合、スタックの値を取得します。その結果である (右下がりの位置, 右上がりの位置) をスタックlayerにpushします(14ー23行目)。
  • スタック layer は、水たまりを各高さの行で分割した組がpushされています。スタックの値を、同じ水たまりに含まれている場合は続けて読み出し、その水たまりの量を求めることができます。結果を result に格納します(27ー41行目)。

配列 result は、右から格納していくため、逆に出力しています(45行目)。

以下が、最終的なC++プログラムとなります。

#include <iostream>
#include <string>
#include <vector>
#include <stack>
using namespace std;

int main()
{
	string s;
	cin >> s;

	stack<int> pos;
	stack<pair<int, int>> layer;
	for (int i = 0; i < s.length(); ++i) {
		if (s[i] == '\\') {
			pos.push(i);
		} else if (s[i] == '/') {
			if (!pos.empty()) {
				layer.push(make_pair(pos.top(), i));
				pos.pop();
			}
		}
	}

	int sum = 0;
	vector<int> result;
	while (!layer.empty()) {
		pair<int, int> this_layer = layer.top();
		layer.pop();
		int left = this_layer.first;
		int this_sum = 0;
		sum += this_layer.second - left;
		this_sum += this_layer.second - left;
		while (!layer.empty()&&(left < layer.top().first)) {
			pair<int, int> next_layer = layer.top();
			layer.pop();
			sum += next_layer.second - next_layer.first;
			this_sum += next_layer.second - next_layer.first;
		}
		result.push_back(this_sum);
	}

	cout << sum << endl;
	cout << result.size();
	for (int i = result.size() - 1; i >= 0; --i) {
		cout << " " << result[i];
	}
	cout << endl;

	return 0;
}

上記プログラムは、AOJ で「AC(Accepted=正解)」と判定されました。

最後に

スタックを2個使うことによって、問題を解くことができました。実装も多めだと思います。

引き続き、ALDS1 の問題を紹介していきます。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA