- CODE FESTIVAL 2015 あさぷろ Easy B - ヘイホー君と置き換え
- CODE FESTIVAL 2017 qual C B - Similar Arrays
- AtCoder Grand Contest 029 A - Irreversible operation
AtCoder ProblemsのRecommendation(Moderate)を解く
CODE FESTIVAL 2015 あさぷろ Easy B - ヘイホー君と置き換え
diff=430くらい
リンク:B - ヘイホー君と置き換え (atcoder.jp)
概要:文字列を前半後半に分けて、前半=後半にするために必要な操作数を出力してね
よくある文字列の置換操作の操作数を求める問題です。
今回は文字を自由に置き換えできるので簡単です。
(文字目と文字目を入れ替えみたいな制約が無い)
まずの文字数が奇数の場合は前半後半に分割不可能なのでを出力します。
偶数なら最悪全文字を置き換えれば題意は満足できます。
とりあえずの頭から文字目までを前半として文字列、文字目から最後を後半として文字列としました。
スライス記法で]とすることで ~ 文字目までを取り出しています。
あとはからまで走査して文字が異なる場所を数え上げれば答えになります。
実際に文字列を置換する必要はありません。
N = int(input())
S = input()
if N % 2 != 0:
print(-1)
else:
A = S[:N//2]
B = S[N//2:]
count = 0
for i in range(N//2):
if A[i] != B[i]:
count += 1
print(count)
提出リンク:提出 #50230109 - CODE FESTIVAL 2015 あさぷろ Easy (atcoder.jp)
CODE FESTIVAL 2017 qual C B - Similar Arrays
diff=430くらい
リンク:B - Similar Arrays (atcoder.jp)
概要:配列の各要素に対して配列の各要素 or or としたときの配列の全項の積が偶数になるパターン数を出力してね
配列長さの制約が10以下なので最悪全探索してもパターンなので間に合いそうです。
が、多重for文でややこしくなりそうなので別の方法を考えます。
今回は積が偶数か奇数かだけ分かればいいという点を使います。
かける数に1つでも偶数があれば積は偶数になります。
逆に言えばすべて奇数をかけるパターンでしか積が奇数になりません。
つまり全パターンから配列の全要素が奇数のパターンの数を引くことで答えとなります。
またが偶数ならの範囲で奇数となりえるのは2通り()あり、が奇数ならの範囲で奇数となりえるのは1通り()あります。
配列の各要素について偶奇判定を行うことでの全項が奇数になるパターン数を把握できます。
これにより計算量で答えを求めることができます。
N = int(input())
A = list(map(int,input().split()))
count = 1
for i in A:
if i % 2 == 0:
count *= 2
else:
count *= 1
print(3**N - count)
提出リンク:提出 #50230176 - CODE FESTIVAL 2017 qual C (atcoder.jp)
AtCoder Grand Contest 029 A - Irreversible operation
diff=430くらい
リンク:A - Irreversible operation (atcoder.jp)
概要:とからなる文字列についての並びをにする操作を可能な限りやって最大回数を出力してね
これもよくある文字列のスワップです。
この問題では文字列の長さが最大なので計算量でないとTLEになります。
つまり文字列を頭から走査してのスワップをする動作を愚直に繰り返す方法では計算量が最悪となるためACできません。
(例えばが個並んだあとにがあるような並び)
ということで、題意の操作を繰り返すと最終的にどういう形になるか、それに対して初期値はどのくらい離れた状態にあるのかを考えることにします。
の並びをにするということは言い換えるとを左側に、を右側に固めることになります。
例として入力例2のは6回の操作で最終的にの並びになるはずです。
の位置に着目して、最初は番目にありますが最終的には番目に移動しています。
1つ目はの距離を、2つ目はの距離を、3つ目はの距離を移動していることがわかります。
移動距離の総和をとると6となりこれが答えとなります。
実際には複数あるを区別する必要はないので、各の初期位置の総和と操作完了後のの位置の総和を引き算することで答えを出します。
ちなみに~の総和はで計算できます。
文字列を1巡だけ走査すれば目的を果たせるので計算量はとなり十分高速です。
S = input()
N = len(S)
count = 0
dist = 0
for i in range(N):
if S[i] == 'W':
count += 1
dist += i
W = (count*(count-1))//2
print(abs(W-dist))
提出リンク:提出 #50230261 - AtCoder Grand Contest 029