Official

D - Japanese Cursed Doll Editorial by mechanicalpenciI


現在から \((T-1)\) 日後には \(N\) 人の髪の長さはすべて \(T\) 以上であり、\(P\leq N\) とあわせて、かならず条件をみたしています。
よって、 \(i=0,1,,\ldots,(T-1)\) について現在から \(i\) 日後に条件をみたしているか順に確認していくことで、答え、すなわち初めて条件をみたす日を求めることができます。

条件をみたしているかの確認は for 文および if 文を用いることで実装できます。計算量は \(O(NT)\) であり、今回の制約下で十分高速です。 よって、この問題を解くことができました。

また、この問題はそれぞれの人が何日後に髪の長さが \(T\) 以上になるか記録し、ソートを用いて小さい方から \(P\) 番目の値を求めることで、\(O(N\log N)\) の計算量で解くことができます。

c++ による実装例:

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

int main(void){
	int n,t,p;	
	int l[100];
	int cnt;

	cin >> n >> t >> p;
	for(int i = 0; i < n; i++)cin >> l[i];

	for(int i = 0; i < t; i++){
		cnt=0;
		for(int j = 0; j < n; j++){
			if(l[j]+i >= t)cnt++;
		}
		if(cnt>=p){
			cout<< i <<endl;
			return 0;
		}
	}
	return 0;
}

Python による実装例:

n,t,p=map(int, input().split())
l=list(map(int, input().split()))

for i in range(t):
    cnt=0
    for j in range(n):
        if l[j]+i>=t:
            cnt+=1
    if cnt>=p:
        print(i)
        break

c++ による実装例(別解):

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

int main(void){
	int n,t,p,x;	
	int l[100];

	cin >> n >> t >> p;

	for(int i = 0; i < n; i++){
		cin >> x;
		l[i]=max(0,t-x);
	}
	sort(l,l+n);

	cout << l[p-1] << endl;

	return 0;
}

posted:
last update: