AtCoder

ABC084 D問題(2017-like Number)を解く

AtCoder_ABC084_D

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

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

D問題 2017-like Number(Difficulty : 980)

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

ABC084 D問題 2017-like Number

素数表を作って、指定された性質の整数を求めます。AtCoder Problems による Difficulty は 980 でした。

解答案

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

エラトステネスの篩を用いて、素数表を作ります(4ー31行目)。

その素数表を基に「$N$も $(N+1)/2$ も素数」(2017に似た数)である数の個数の累積和を計算します(44ー52行目)。

区間に含まれる2017に似た数の個数を $O(1)$ の計算量で求めることができます(54ー56行目)。

以下が、C++プログラムです。

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

#define N 100000
bool is_prime_table[N + 1];
vector<int> primes;

void generate_primes(int n)
{
	is_prime_table[0] = false;
	is_prime_table[1] = false;
	for (int i = 2; i <= n; ++i) {
		is_prime_table[i] = true;
	}

	for (int i = 2; i * i <= n; ++i) {
		if (is_prime_table[i]) {
			for (int j = i + i; j <= n; j += i) {
				is_prime_table[j] = false;
			}
		}
	}

	for (int i = 2; i <= n; ++i) {
		if (is_prime_table[i]) {
			primes.push_back(i);
		}
	}

	return;
}

int main()
{
	int q;
	cin >> q;
	vector<int> l(q), r(q);
	for (int i = 0; i < q; ++i) {
		cin >> l[i] >> r[i];
	}

	generate_primes(N);

	vector<int> sum_like2017(N, 0); /* i番目までの「2017に似た数」の累計和 */
	for (int i = 3; i < N; i += 2) {
		if (is_prime_table[i] && is_prime_table[(i + 1) / 2]) {
			sum_like2017[i] = sum_like2017[i - 2] + 1;
		} else {
			sum_like2017[i] = sum_like2017[i - 2];
		}
		sum_like2017[i - 1] = sum_like2017[i - 2];
	}

	for (int i = 0; i < q; ++i) {
		cout << sum_like2017[r[i]] - sum_like2017[l[i] - 1] << endl;
	}

	return 0;
}

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

最後に

整数について3問続けて解説しました。

複数の問題を連続して解説することで、理解を深めることができました。

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

COMMENT

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

CAPTCHA