AtCoder

ABC077 C問題(Snuke Festival)を解く

AtCoder_ABC077_C

AtCoder が提供しているABC(AtCoder Beginner Contest)077 C問題をC++で解いてみました。ABC077は、2017年11月4日21:00に実施されました。

AtCoder の紹介はこちらに、プログラミングの方針はこちらに記事があります。

C問題 Snuke Festival(Difficulty : 1096)

問題の詳細は、リンク先をご覧ください。

ABC077 C問題 Snuke Festival

中部のパーツを固定して、上下のパーツ数を二分探索で調べます。AtCoder Problems による Difficulty は 1096 でした。

解答案

C++ の二分探索を行う lower_boundupper_bound の動作についてまとめます。

求めたい要素数コード
x 未満の配列 a の要素数lower_bound(a.begin(), a.end(), x) - a.begin()
x 以下の配列 a の要素数upper_bound(a.begin(), a.end(), x) - a.begin()
x を超える配列 a の要素数a.end() - upper_bound(a.begin(), a.end(), x);
x 以上の配列 a の要素数a.end() - lower_bound(a.begin(), a.end(), x);

C++ プログラム例(ABC077C)

上部の配列 a と下部の配列 c を読み込み、それぞれソートします(14、23行目)。

中部のパーツを1つ選び、そのパーツより小さい上部のパーツ数(diff1)と大きい下部のパーツ数(diff2)を求め、積を result に加えます(25ー30行目)。

最後に result を出力します。以下が、C++プログラムです。

#include <bits/stdc++.h>
using namespace std;

typedef long long int ll;

int main()
{
	int n;
	cin >> n;
	vector<int> a(n);
	for (int i = 0; i < n; ++i) {
		cin >> a[i];
	}
	sort(a.begin(), a.end());
	vector<int> b(n);
	for (int i = 0; i < n; ++i) {
		cin >> b[i];
	}
	vector<int> c(n);
	for (int i = 0; i < n; ++i) {
		cin >> c[i];
	}
	sort(c.begin(), c.end());

	ll result = 0;
	for (int i = 0; i < n; ++i) {
		ll diff1 = lower_bound(a.begin(), a.end(), b[i]) - a.begin();
		ll diff2 = c.end() - upper_bound(c.begin(), c.end(), b[i]);
		result += diff1 * diff2;
	}

	cout << result << endl;

	return 0;
}

AC(Accepted=正しいプログラム)と判定されました。

最後に

値の二分探索についてまとめました。

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

COMMENT

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

CAPTCHA