AtCoder

ABC342 C問題(Many Replacement)を解く

AtCoder_ABC342_C

AtCoder が提供しているABC(AtCoder Beginner Contest)342 のC問題をC++とPythonで解いてみました。ABC342は、2024年2月24日21:00に実施されました。

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

C問題 Many Replacement(Difficulty : 505)

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

ABC342 C問題 Many Replacement

クエリで文字の変換テーブルを更新して、後でまとめて変換します。AtCoder Problems による Difficulty は 505 でした。

解答案

素朴に、クエリの回数 $Q$ 毎に、長さ $N$ の文字列の変換を行うと、計算量は、$O(NQ) = 2 \times 10^5 \times 2 \times 10^5 = 4 \times 10^{10}$ となり間に合いません。

変換テーブル m を用意します。初期値は、文字を変換しないテーブルとなります。

m[‘a’] = ‘a’, m[‘b’] = ‘b’, …, m[‘z’] = ‘z’

クエリで、c と d を読み込み、ある文字の変換先が c に一致した場合、d に書き換えます。変換テーブルを処理する計算量は、すべての文字について調べるため、$O(26 N) = 5.2 \times 10^6$ となり十分に間に合います。

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

変換テーブルは、map<char, char> を使います。クエリで変換テーブル m を更新して、後で、まとめて文字列を変換します。

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

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

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

	map<char, char> m;
	for (int i = 0; i < 26; ++i) {
		m[(char)(i + 'a')] = (char)(i + 'a');
	}

	int q;
	cin >> q;
	for (int i = 0; i < q; ++i) {
		char c, d;
		cin >> c >> d;
		for (auto e : m) {
			if (e.second == c) {
				m[e.first] = d;
			}
		}
	}

	string result;
	for (int i = 0; i < n; ++i) {
		result += m[s[i]];
	}
	cout << result << endl;

	return 0;
}

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

Python プログラム例(ABC342C)

Python 版も基本的な考え方は同じです。変換テーブルは辞書を使いました。string.ascii_lowercase で、”abc…xyz” が定義されています。以下となります。

"""AtCoder Beginner Contest 342 C"""
from string import ascii_lowercase

n = int(input())
s = input()
m = {}
for _, ch in enumerate(ascii_lowercase):
    m[ch] = ch

q = int(input())
for i in range(q):
    c, d = input().split()
    for ch in m:
        if m[ch] == c:
            m[ch] = d

result = ""
for _, ch in enumerate(s):
    result += m[ch]
print(result)

こちらも「AC」と判定されました。

最後に

C問題からは、素朴なプログラムでは時間が間に合わない場合がでてきます。この問題は、変換テーブルだけを処理することがポイントでした。

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

COMMENT

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

CAPTCHA