İnək Akademiyası I#11231

İnək Akademiyası I (Həll təhlili)

Verilmiş ədədlər massivi üçün -indeksin necə müəyyən ediləcəyini nəzərdən keçirək. Əvvəlcə massivi azalan sırada düzəldək. Sonra elə ən böyük dəyərini tapaq ki, -dən -a qədər olan mövqelərdəki elementlər -dan kiçik olmasın. Başqa sözlə, a_h \ge h şərtini ödəyən maksimal -ı axtarırıq.

Məsələn, aşağıdakı halda -indeks -ə bərabərdir, çünki a_3 \ge 3, lakin a_4 < 4.

sitatı əlavə etdikdən sonra -indeks -dən çox arta bilməz. Həqiqətən, a_{h+1} < h + 1 olduğundan və hər məqaləyə ən çoxu bir dəfə istinad etmək mümkün olduğundan, edə biləcəyimiz maksimum şey a_{h + 1}-i artırmaqdır (əgər əvvəlcədən a_{h + 1} = h olarsa).

Sonra h + 1 mövqeyindən başlayaraq daha kiçik indekslər istiqamətində hərəkət edərək massivin elementlərini artıracağıq. Başqa sözlə, a[\max(1, h - l + 2); h + 1] parçasındakı elementləri artıracağıq.

Bundan sonra massivi yenidən azalan sıraya görə düzəldib -indeksi yenidən hesablayacağıq. Alınan dəyər cavab olacaq.

Nümunə

Birinci nümunədə Bessi öz məqalələrinə istinad edə bilmir, buna görə də (1, 100, 2, 3) dəsti üçün onun -indeksi -yə bərabərdir.

İkinci nümunədə, əgər Bessi üçüncü məqaləyə istinad edərsə, sitatların sayı (1, 100, 3, 3) olar. Bu halda -indeks -ə qədər artacaq.

Aşağıdakı nümunəni nəzərdən keçirək. Ədədlər artıq azalan sırada verilmişdir. Bu massivin -indeksi -ə bərabərdir.

Alqoritmin reallaşdırılması

hIndex funksiyası əvvəlcədən azalan sıraya görə düzədilmiş massiv üçün -indeksi hesablayır. İndeksləmə -dən başlayır. Funksiya v_i \ge i şərtini ödəyən maksimal dəyərini qaytarır. Əgər belə indeks yoxdursa (-indeks massivinin -ə bərabər olduğu hal), onda -ə bərabər olan v.size() - 1 dəyərini qaytarırıq.

int hIndex(vector<int> &v)
{
  for (int i = 1; i < v.size(); i++)
    if (v[i] < i) return i - 1;
  return v.size() - 1;
}

Proqramın əsas hissəsi. Giriş məlumatlarını oxuyuruq.

scanf("%d %d", &n, &l);
v.resize(n + 1);
for (i = 1; i <= n; i++)
  scanf("%d", &v[i]);

Massivi birinci elementdən başlayaraq azalan sıraya görə düzəldirik.

sort(v.begin() + 1, v.end(), greater<int>());

İlkin massivin -indeksini hesablayırıq.

h = hIndex(v);

h + 1 mövqeyindən başlayaraq daha kiçik indekslər istiqamətində hərəkət edərək müvafiq v_i dəyərlərini artırırıq.

for (i = h + 1; i > max(h - l + 1, 0); i--)
  v[i]++;

Massivi azalan sıraya görə düzəldib onun yeni -indeksini hesablayırıq.

sort(v.begin() + 1, v.end(), greater<int>());
h = hIndex(v);

Cavabı çap edirik.

printf("%d\n", h);