公式

D - 1D Pawn 解説 by mechanicalpenciI


各操作の前後で、各コマはそれぞれ相異なるマスにおかれており、 さらに操作によってコマが他のコマを飛び越えることが無いこと(すなわち、元々あるコマの左のマスにあったコマが操作の後でそのコマの右のマスに存在するようなこと)に注意します。

このことから、最初左から \(i\) 番目にあったコマは、その後の操作によらずつねに \(K\) 個の中で左から \(i\) 番目にある事が分かります。 よって、最初の配置において左にあったコマから順にコマ \(1\), コマ \(2\), \(\ldots\), コマ \(K\) と番号を付けると、コマ \(i\) はつねに左から \(i\) 番目のコマであり、操作は次のように書き換えることができます。

  • コマ \(L_i\) がマス \(N\) にあるならば何も行わない。
  • そうでない時、コマ \(L_i\) があるマスの \(1\) つ右のマスにコマが無いならば、コマ \(L_i\)\(1\) つ右のマスに移動させる。 \(1\) つ右のマスにコマがあるならば、何も行わない。

このとき \(1\) つ右のマスにある可能性のあるコマがコマ \(L_i+1\) しかない (\(L_i=K\) ならば存在しない) ことに注意すると、さらに次のように書き直せます。

  • コマ \(L_i\) がマス \(N\) にあるならば何も行わない。
  • そうでない時、\(L_i=K\) ならばコマ \(L_i\)\(1\) つ右のマスに移動させる。
  • 上のいずれでもない時、コマ \(L_i+1\) があるマスがコマ \(L_i\) があるマスの \(1\) つ右のマスでないならば、コマ \(L_i\)\(1\) つ右のマスに移動させる。 \(1\) つ右のマスであるならば、何も行わない。

これに従って、コマ \(i\) があるマスの番号を配列 \(A[i]\) 等で管理しながら操作に合わせて更新していく事で、この問題を解いてあげることができます。

最後に \(A[i]\) を順に出力すればよいです。 よって、この問題を解くことができました。

なお、番兵として、マス \(N+1\) とコマ \(K+1\) が存在して 、コマ \(K+1\) がつねにマス \(N+1\) にあるとしてあげると、\(L_i=K\) のときについてもその他の場合と同様に処理ができて楽になります。

c++ による実装例(番兵なし) :

#include <bits/stdc++.h>
using namespace std;
int main() {
	int n, k, q;
	int a[201];
	int x;

	cin >> n >> k >> q;
	for (int i = 1; i <= k; i++)cin >> a[i];

	for (int i = 0; i < q; i++) {
		cin >> x;
		if (a[x] == n)continue;
		else if (x == k)a[x]++;
		else if (a[x] + 1 < a[x + 1])a[x]++;
	}

	for (int i = 1; i <= k; i++) {
		cout << a[i];
		if (i < k)cout << " ";
		else cout << endl;
	}

	return 0;
}

c++ による実装例(番兵あり) :

#include <bits/stdc++.h>
using namespace std;
int main() {
	int n, k, q;
	int a[202];
	int x;

	cin >> n >> k >> q;
	for (int i = 1; i <= k; i++)cin >> a[i];
	a[k + 1] = n + 1;

	for (int i = 0; i < q; i++) {
		cin >> x;
		if (a[x] + 1 < a[x + 1])a[x]++;
	}

	for (int i = 1; i <= k; i++) {
		cout << a[i];
		if (i < k)cout << " ";
		else cout << endl;
	}

	return 0;
}

Python による実装例 :

n,k,q = map(int, input().split())
a = list(map(int,input().split()))
l= list(map(int,input().split()))

for i in range(q):
    if(a[l[i]-1] == n):
        continue
    elif(l[i]==k):
        a[l[i]-1]+=1
    elif(a[l[i]-1]+1<a[l[i]]):
        a[l[i]-1]+=1

print(*a)

投稿日時:
最終更新: