---
# System prepended metadata

title: Разбор задач 2016 года

---

# Разбор задач 2016 года
Если Вы не знали как решать какую-то задачу и Вам было лень разбираться в коде на Pascal, то это пост специально для Вас.
:::warning
Убедительная просьба не копировать коды и не пересылать их. Помните -- Вы решаете задачи для себя!
:::

## [1. Движение по кольцу](https://codeforces.com/group/skz9fIV5Hq/contest/261187/problem/2016_1)
:::spoiler Разбор
:::info
Паша может жить либо на $m$ остановок левее школы, либо на $m$ остановок правее школы. Считаем местоположение дома Паши. Не забудем, что его можно определить однозначно. 

Асимптотика: $O(1)$.
:::
:::spoiler Авторское решение (Pascal)
```pascal
var
n,m,k,x1,x2:longint;
begin
   read(n,k,m);
   x1:=(k + m) mod n + 1;
   x2:=(n + k - m - 2) mod n + 1;
   if 2*m+2>=n then
      if x1=x2 then writeln(x1)
      else if x1<x2 then writeln(x1, ' ', x2)
      else writeln(x2, ' ', x1)
end.
```
:::
:::spoiler Код (C++, автор: [Adamenko](https://codeforces.com/profile/Adamenko))
```cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
    long long n, m, k;
    cin >> n >> k >> m;
    m++;
    set<long long> ans;
    long long ost_1 = k - m;
    if (ost_1 >= 1)
        ans.insert(ost_1);
    else ans.insert(ost_1 + n);
    long long ost_2 = k + m;
    if (ost_2 <= n)
        ans.insert(ost_2);
    else ans.insert(ost_2 - n);
    for (auto to : ans)
        cout << to << " ";
    cout << endl;
    return 0;
}
```
:::

## [2. Крутейший спуск](https://codeforces.com/group/skz9fIV5Hq/contest/261187/problem/2016_2)
:::spoiler Разбор
:::info
В этой задаче нам нужно найти максимальное отношение перепада высот к расстоянию между отметками по горизонтали. Мы делаем ровно то, о чем нас просят. Единственный момент: чтобы избежать неточностей, давайте заменим отношение умножением крест-накрест ($\frac{A}{B} = \frac{C}{D}$ равносильно $A * D = B * C$).
Асимптотика: $O(N)$.
:::
:::spoiler Авторское решение (Pascal)
```pascal
function abs(x:longint):longint;
begin
   if x<0 then abs:=-x else abs:=x
end;
var
n,xp,hp,xc,hc,i,mp,dx,dh,mdx,mdh:longint;
begin
   read(n);
   read(xp,hp,xc,hc);
   mp:=1;
   mdx:=abs(xp-xc);
   mdh:=abs(hp-hc);
   for i:=2 to n-1 do begin
      xp:=xc;hp:=hc;
      read(xc,hc);
      dx:=abs(xp-xc);
      dh:=abs(hp-hc);
      if int64(dh)*mdx>int64(mdh)*dx then begin
	 mp:=i;
	 mdx:=dx;
	 mdh:=dh
      end
   end;
   writeln(mp)
end.
```
:::
:::spoiler Код (C++, автор: [gamora](https://codeforces.com/profile/gamora))
```cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
    int n;
    cin >> n;
    int lasth, lastd;
    cin >> lastd >> lasth;
    int d, h;
    cin >> d >> h;
    int H = abs(lasth - h);
    int D = abs(lastd - d);
    int otH = H, otD = D, nom = 1, j = 1;
    for (int i = 2; i < n; i++) {
        j++;
        lastd = d;
        lasth = h;
        cin >> d >> h;
        H = abs(lasth - h);
        D = abs(lastd - d);
        if (otH * D < H * otD) {
            otH = H;
            otD = D;
            nom = j;
        }
    }
    cout << nom << endl;
    return 0;
}
```
:::

## [3. Самый длинный слог](https://codeforces.com/group/skz9fIV5Hq/contest/261187/problem/2016_3)
:::spoiler Разбор
:::info
Это очень запарная и неприятная реализация. Разбираем все случаи (они описаны в условии). Выводим ответ.

Асимптотика: $O(N + |allS|)$, где $|allS|$ -- длина всех строк.
:::
:::spoiler Авторское решение (Pascal)
```pascal
var
i,st,p,m,mp,k:longint;
s:ansistring;
begin
   readln(s);
   st:=1;
   p:=0;
   m:=0; mp:=0;
   for i:=1 to length(s) do
      case s[i] of
	    ' ': begin
	        if m < i-st then begin m:=i-st; mp:=st end;
	        st:=i+1;
	        p:=0
	    end;
	    'a','e','i','o','u','y'	: begin
	        if p<>0 then begin
	            if (s[p] = 'y') or (i<=p+2) then k := p else k:=p+1;
	            if m < k + 1 - st then begin m := k + 1 - st; mp:=st end;
	            st := k + 1
	        end;
	        p:=i
	    end
    end;
   k:=length(s);
   if m < k + 1 - st then begin m := k + 1 - st; mp:=st end;
   writeln(copy(s,mp,m))
end.
```
:::
:::spoiler Код (C++, автор: [Zhdun](https://codeforces.com/profile/Zhdun))
```cpp
#include <bits/stdc++.h>
using namespace std;

vector<string> w;

int main() {
    string s;

    getline(cin,s);
    string cur = "";
    for (int i = 0; i < s.size(); i++)
        if (s[i] == ' ') {
            w.push_back(cur);
            cur = "";
        } else cur += s[i];
    if (cur != "")
        w.push_back(cur);

    int ma=0;
    string ans;

    for (int i = 0; i < w.size(); i++) {
        vector<int> gl;
        int pr = -1;
        for (int j = 0; j < w[i].size(); j++)
            if (w[i][j]=='a' || w[i][j]=='e' || w[i][j]=='y' || w[i][j]=='i' || w[i][j]=='o' || w[i][j]=='u')
                gl.pb(j);
        int cur = 0;
        string t;

        for (int j = 0; j < w[i].size(); j++)
            if (cur == 0 && j < gl[0])
                t += w[i][j];
            else if(cur == gl.size()-1 && j >= gl[cur])
                t+=w[i][j];
            else if (gl[cur] == j && cur != gl.size()-1) {
                t += w[i][j];
                cur++;
                if (gl[cur] - gl[cur-1] <= 2 || w[i][j] == 'y') {
                    if (t.size() > ma) {
                        ans = t;
                        ma = t.size();
                    }
                    t = "";
                }
            } else if (gl[cur-1] == j-1) {
                t += w[i][j];
                if (t.size()>1) {
                    if (t.size() > ma) {
                        ans = t;
                        ma = t.size();
                    }
                    t = "";
                }
            } else t+=w[i][j];

        if(t != "") {
            if (t.size() > ma) {
                ans = t;
                ma = t.size();
            }
            t = "";
        }
    }

    cout << ans << endl;
}
```
:::

## [4. Пессимистичный прогноз](https://codeforces.com/group/skz9fIV5Hq/contest/261187/problem/2016_4)
:::spoiler Разбор
:::info
Давайте напишем жадный алгоритм. Вначале отсортируем все команды по рейтингу (он описан в условии). Теперь все команды, которые выше $k$-й, мы трогать не будем (выдавать медали). Оставшимся командам будем жадно выдавать медали по следующему алгоритму:
1. Пытаемся выдать на $1$ бронзовую медаль больше, чем у $k$-й (если можем), при этом уравниваем количество золотых и серебрянных медалей.
2. Пытаемся выдать на $1$ серебрянную медаль больше, чем у $k$-й (если можем), при этом уравниваем количество золотых медалей.
3. Пытаемся выдать на $1$ золотую медаль больше чем у $k$-й (если можем).

Асимптотика решения: $O(N * log(N))$.
:::
:::spoiler Авторское решение (Pascal)
```pascal
var
n,k,i,ig,wani4ka,ib,x,mx:integer;
rg,rs,rb:integer;
g,s,b:array[1..300]of byte;
f:array[0..300,0..60,0..60,0..60] of integer;
{p:array[1..300,0..60,0..60,0..60] of (gold,silver,bronze,none);}
function greater:boolean;
begin
   if g[i]=g[k] then
      if s[i]=s[k] then greater:=b[i]>b[k]
      else greater:=s[i]>s[k]
   else greater:=g[i]>g[k]
end;
function byGold:integer;
var dg:integer;
begin
   dg:=g[k]-g[i]+1;
   if dg<=ig then byGold:=f[i-1,ig-dg,wani4ka,ib]+1
   else byGold:=0
end;
function bySilver:integer;
var dg,ds:integer;
begin
   dg:=g[k]-g[i];
   ds:=s[k]-s[i]+1;
   if ds < 0 then ds := 0;
   if (dg<=ig) and (ds<=wani4ka) then bySilver:=f[i-1,ig-dg,wani4ka-ds,ib]+1
   else bySilver:=0
end;
function byBronze:integer;
var dg,ds,db:integer;
begin
   dg:=g[k]-g[i];
   ds:=s[k]-s[i];
   if ds >= 0 then begin
      db:=b[k]-b[i]+1;
      if db < 0 then db := 0;
      if (dg<=ig) and (ds<=wani4ka) and (db<=ib) then
	 byBronze:=f[i-1,ig-dg,wani4ka-ds,ib-ib]+1
      else byBronze:=0;
   end else byBronze:=0;
end;
begin
   read(n,k,rg,rs,rb);
   for i:=1 to n do read(g[i],s[i],b[i]);
   for ig:=0 to rg do
      for wani4ka:=0 to rs do
	 for ib:=0 to rb do
	    f[0,ig,wani4ka,ib]:=0;
   for i:=1 to n do
      if i=k then
	 for ig:=0 to rg do
	    for wani4ka:=0 to rs do
	       for ib:=0 to rb do begin
		  f[i,ig,wani4ka,ib]:=f[i-1,ig,wani4ka,ib];
//		  p[i,ig,wani4ka,ib]:=none;
	       end
      else if greater then
	 for ig:=0 to rg do
	    for wani4ka:=0 to rs do
	       for ib:=0 to rb do begin
		  f[i,ig,wani4ka,ib]:=f[i-1,ig,wani4ka,ib]+1;
//		  p[i,ig,wani4ka,ib]:=none;
	       end		  
      else
	 for ig:=0 to rg do
	    for wani4ka:=0 to rs do
	       for ib:=0 to rb do begin
		  f[i,ig,wani4ka,ib]:=f[i-1,ig,wani4ka,ib];
//		  p[i,ig,wani4ka,ib]:=none;
		  x:=byGold;
		  if x>f[i,ig,wani4ka,ib] then begin
		     f[i,ig,wani4ka,ib]:=x;
//		     p[i,ig,wani4ka,ib]:=gold
		  end;
		  x:=bySilver;
		  if x>f[i,ig,wani4ka,ib] then begin
		     f[i,ig,wani4ka,ib]:=x;
//		     p[i,ig,wani4ka,ib]:=silver
		  end;		     
		  x:=byBronze;
		  if x>f[i,ig,wani4ka,ib] then begin
		     f[i,ig,wani4ka,ib]:=x;
//		     p[i,ig,wani4ka,ib]:=bronze
		  end
	       end;
   mx:=0;
   for ig:=0 to rg do
      for wani4ka:=0 to rs do
	 for ib:=0 to rb do
	    if f[n,ig,wani4ka,ib]>mx then begin
	       mx:=f[n,ig,wani4ka,ib];
{	       mig:=ig;
	       mis:=wani4ka;
	       mib:=ib}
	    end;
   writeln(mx);
{   i:=n;
   while i>0 do begin
      case p[i,mig,mis,mib] of
	gold   : begin
		    writeln(i);
		    mig:=mig-(g[k]-g[i]+1)
		 end;
	silver : begin
		    writeln(i);
		    mig:=mig-(g[k]-g[i]);
		    mis:=mis-(s[k]-s[i]+1)
		 end;
	bronze : begin
		    writeln(i);
		    mig:=mig-(g[k]-g[i]);
		    mis:=mis-(s[k]-s[i]);
		    mib:=mib-(b[k]-b[i]+1)
		 end;
      end;
      i:=i-1
   end}
end.
```
:::
:::spoiler Код (C++, автор: [Adamenko](https://codeforces.com/profile/Adamenko))
```cpp
#include <bits/stdc++.h>
using namespace std;

struct node {
    int Gold, Silver, Bronze;
    int id;
    node() {
        Gold = 0;
        Silver = 0;
        Bronze = 0;
        id = -1;
    }
    bool operator < (const node &x) {
        if (x.Gold != Gold) return x.Gold > Gold;
        else if (x.Silver != Silver) return x.Silver > Silver;
        else return x.Bronze > Bronze;
    }
};

vector<node> all;

int kol_Gold = 0;
int kol_Silver = 0;
int kol_Bronze = 0;

int main() {
    int n, k;
    cin >> n >> k >> kol_Gold >> kol_Silver >> kol_Bronze;
    all.resize(n);
    for (int i = 0; i < n; ++i) {
        cin >> all[i].Gold >> all[i].Silver >> all[i].Bronze;
        all[i].id = i + 1;
    }
    sort(all.rbegin(), all.rend());
    int ans = 0;
    bool ok = 1;
    node Team;
    for (int i = 0; i < n; ++i) {
        if (all[i].id != k && ok) {
            ans++;
            continue;
        }
        if (all[i].id == k) {
            ok = 0;
            Team = all[i];
            continue;
        }
        int need_Gold = -all[i].Gold + Team.Gold;
        int need_Silver = -all[i].Silver + Team.Silver;
        int need_Bronze = -all[i].Bronze + Team.Bronze;
        if (need_Gold <= kol_Gold && need_Silver <= kol_Silver && need_Bronze + 1 <= kol_Bronze) {
            kol_Gold -= (need_Gold < 0 ? 0 : need_Gold);
            kol_Silver -= (need_Silver < 0 ? 0 : need_Silver);
            kol_Bronze -= (need_Bronze >= 0 ? need_Bronze + 1 : 0);
            ans++;
            continue;
        }
        if (need_Gold <= kol_Gold && need_Silver + 1 < kol_Silver) {
            kol_Gold -= (need_Gold < 0 ? 0 : need_Gold);
            kol_Silver -= (need_Silver >= 0 ? need_Silver + 1 : 0);
            ans++;
            continue;
        }
        if (need_Gold + 1 <= kol_Gold) {
            kol_Gold -= (need_Gold >= 0 ? need_Gold + 1 : 0);
            ans++;
            continue;
        }
    }
    cout << ans << endl;
    return 0;
}
```
:::