---
# System prepended metadata

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

---

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

## [1. Тренировка (усложнённая версия)](https://codeforces.com/group/skz9fIV5Hq/contest/261187/problem/2012_1)
:::spoiler Разбор
:::info
Давайте посчитаем динамику $dp_i$ -- максимальная сумма чисел, которую мы можем собрать, дойдя до клетки под номером $i$. 

Два перехода:
1. $dp_i = dp_{i - 2} + a_i$
2. $dp_i = dp_{i - 3} + a_i$

__Не забываем хранить предков!__

Асимптотика: $O(N)$.
:::
:::spoiler Авторское решение (Pascal)
```pascal
program z1221s1;
const
  max_n=1000;
var
  A:array[1..max_n] of integer;
  F:array[1..max_n] of longint;
  P,S:array[1..max_n] of byte;
  n,i,k:integer;
begin
  readln(n);
  for i:=1 to n do
    read(a[i]);
  f[1]:=a[1];p[1]:=2;
  f[2]:=a[2];p[2]:=3;
  if n>2 then begin
    f[3]:=f[1]+a[3];p[3]:=2;
    for i:=4 to n do
      if f[i-2]+a[i]<f[i-3]+a[i] then
        begin f[i]:=f[i-3]+a[i];p[i]:=3 end
      else
        begin f[i]:=f[i-2]+a[i]; p[i]:=2 end
  end;
  k:=1;
  if f[n]>f[n-1] then s[1]:=2 else s[1]:=3;
  i:=n+2-s[1];
  while i>2 do begin
    k:=k+1;
    s[k]:=p[i];
    i:=i-s[k]
  end;
  k:=k+1;
  s[k]:=i+1;
  writeln(k);
  for i:=k downto 2 do
    write(s[i],' ');
  writeln(s[1]);
end.
```
:::
:::spoiler Код (C++, автор: [Adamenko](https://codeforces.com/profile/Adamenko))
```cpp
#include <bits/stdc++.h>
using namespace std;

const ll mod = 1e9 + 7;
const int FFTM = 998244353;
const int N = 1e3 + 15;
const int SX[4] = {0 , 1 , -1 , 0};
const int SY[4] = {1 , 0 , 0 , -1};
const int rx[8] = {1, -1, 0, 0, 1, 1, -1, -1};
const int ry[8] = {0, 0, 1, -1, 1, -1, 1, -1};
const int kx[8] = {1, 1, -1, -1, 2, 2, -2, -2};
const int ky[8] = {2, -2, 2, -2, 1, -1, 1, -1};

long long dp[N];
int pr[N];

int main() {
    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; ++i)
        cin >> a[i];
    dp[0] = a[0];
    pr[0] = -1;
    dp[1] = a[1];
    pr[1] = -1;
    for (int i = 2; i < n; ++i)
        if (i == 2) {
            dp[i] = dp[i - 2] + a[i];
            pr[i] = i - 2;
        } else if (dp[i - 2] + a[i] > dp[i - 3] + a[i])
            dp[i] = dp[i - 2] + a[i], pr[i] = i - 2;
        else dp[i] = dp[i - 3] + a[i], pr[i] = i - 3;
    int posl;
    int pos = -1;
    vector<int> ans;
    if (dp[n - 1] < dp[n - 2])
        posl = 3, pos = n - 2;
    else posl = 2, pos = n - 1;
    while (pos != -1) {
        int x = pos;
        pos = pr[pos];
        if (pos == -1) {
            if (x == 1) ans.push_back(3);
            else ans.push_back(2);
        } else ans.push_back(x - pos);
    }
    cout << ans.size() + 1 << endl;
    reverse(ans.begin(), ans.end());
    for (auto to : ans) cout << to << " ";
    cout << posl << endl;
    return 0;
}
```
:::

## [2. Паша и системы счисления](https://codeforces.com/group/skz9fIV5Hq/contest/261187/problem/2012_2)
:::spoiler Разбор
:::info
Самое сложное в этой задаче -- это понять ее условие.

Сначала нам нужно перевести данную нам строку в число, по описанному в условии алгоритму. Затем нужно перевести полученное число обратно в строку, по описанному в условии алгоритму. Если полученная строка совпадает со строкой из входных данных, то нам нужно вывести число, иначе строку. 

Асимптотика: $O(len)$, где $len$ -- это длина числа. 

:::
:::spoiler Авторское решение (Pascal)
```pascal
program z1222s1;
var
  wu,wh,wf:array[0..3] of char;
function vCode(k,d:byte):string;
begin
    case d of
      0:vCode:='';
      1:vCode:=wu[k];
      2:vCode:=wu[k]+wu[k];
      3:vCode:=wh[k]+wu[k];
      4:vCode:=wh[k];
      5:vCode:=wu[k]+wh[k];
      6:vCode:=wf[k]+wu[k]
    end
end;
function cValue(c:char):word;
begin
  case c of
    'T':cValue:=1;
    'W':cValue:=4;
    'Y':cValue:=7;
    'Z':cValue:=28;
    'K':cValue:=49;
    'E':cValue:=196;
    'F':cValue:=343;
    'H':cValue:=1372
  end
end;
var
  s,c:string[30];
  v,x,v0,v1:word;
  i,k:integer;
begin
  wu[0]:='T';wh[0]:='W';wf[0]:='Y';
  wu[1]:='Y';wh[1]:='Z';wf[1]:='K';
  wu[2]:='K';wh[2]:='E';wf[2]:='F';
  wu[3]:='F';wh[3]:='H';wf[3]:=#0;
  readln(s);
  v0:=cValue(s[1]);
  v:=v0;
  for i:=2 to length(s) do begin
    v1:=v0;
    v0:=cValue(s[i]);
    if v0>=v1 then v:=v+v0 else v:=v-v0
  end;
  x:=v;
  k:=0;
  c:='';
  while x>0 do begin
    v0:=x mod 7;
    x:=x div 7;
    c:=c+vCode(k,v0);
    k:=k+1
  end;
  if c=s then writeln(v) else writeln(c);
end.
```
:::
:::spoiler Код (C++, автор: [Sokolovskaya](https://codeforces.com/profile/Sokolovskaya))
```cpp
#include <bits/stdc++.h>
using namespace std;

map<int, string> ss;
vector<string> kek;

void change(int j) {
    j *= 2;
    ss[1] = kek[j];
    ss[2] = kek[j] + kek[j];
    ss[3] = kek[j + 1] + kek[j];
    ss[4] = kek[j + 1];
    ss[5] = kek[j] + kek[j + 1];
    ss[6] = kek[j + 2] + kek[j];
}

int32_t main() {
    string s;
    cin >> s;
    map<char, int> mp;
    mp['T'] = 1;
    mp['W'] = 4;
    mp['Y'] = 7;
    mp['Z'] = 28;
    mp['K'] = 49;
    mp['E'] = 196;
    mp['F'] = 343;
    mp['H'] = 1372;
    kek.push_back("T"); kek.push_back("W"); kek.push_back("Y"); kek.push_back("Z"); kek.push_back("K"); kek.push_back("E"); kek.push_back("F"); kek.push_back("H"); kek.push_back("a");
    int n = s.size();
    vector<int> a(n);
    for (int i = 0; i < n; ++i)
        a[i] = mp[s[i]];
    int ans = a[0];
    for(int i = 1; i < n; ++i) {
        int z = 1;
        if(a[i] < a[i - 1]) z = -1;
        ans += z * a[i];
    }
    int x = ans;
    int sz = 0;
    vector<int> b;
    while(x) {
        b.pb(x % 7);
        x /= 7;
        ++sz;
    }
    string res = "";
    for (int i = 0; i < b.size(); ++i) {
        change(i);
        if(b[i] == 0) continue;
        res += ss[b[i]];
    }
    cout << (s == res ? ans : res) << endl;
    return 0;
}
```
:::

## [3. Библиотека](https://codeforces.com/group/skz9fIV5Hq/contest/261187/problem/2012_3)
:::spoiler Разбор
:::info
Давайте каждой книжке дадим свой номер, который показывает, какой по счету была поставлена эта книжка в библиотеку.

Теперь зная порядковый номер каждой книжки, мы легко можем найти номер ряда, шкафа, полки и позиции данной книжки. 

Уточнить формулы нахождения ряда, шкафа, полки и позиции Вы можете, посмотрев код.

Асимптотика: $O(min(M * N, 10^7))$.

*P.S:*
*Вывести формулки лучше самому, чем их копипастить.*

:::
:::spoiler Авторское решение (Pascal)
```pascal
program z1223s5;

const
  max_n=100000;
  max_m=10000;
  max_k=100000;
  max_v=1000;
  max_books=10000000;
  max_b=100;
  max_s=10;
  max_r=1000;

var
  qtitle:array[1..max_k]of integer;
  qindex,qplace,qans:array[1..max_k] of longint;
  title,damount:array[1..max_n] of integer;
  tamount:array[1..max_m] of longint;
  qtstart,qtend:array[1..max_m] of longint;
  n,k,i,j,p:longint;
  m,r:integer;
  b,s:byte;

procedure PrintPlace(var p:longint);
var
  ri,bi,si:longint;
begin
  p:=p-1;
  si:=p div b;
  p:=p mod b;
  bi:=si div s;
  si:=si mod s;
  ri:=bi div r;
  bi:=bi mod r;
  writeln(ri+1,' ',bi+1,' ',si+1,' ',p+1)
end;

function compare(t1,i1,t2,i2:longint):longint;
begin
  if t1<>t2 then compare:=t1-t2
  else compare:=i1-i2
end;

procedure swap(j,k:longint);
var
  tmp:longint;
begin
  tmp:=qtitle[j];qtitle[j]:=qtitle[k];qtitle[k]:=tmp;
  tmp:=qindex[j];qindex[j]:=qindex[k];qindex[k]:=tmp;
  tmp:=qplace[j];qplace[j]:=qplace[k];qplace[k]:=tmp
end;

procedure SortRequests;
var
  i,j,d:longint;
begin
  for i:=2 to k do begin
    j:=i;
    d:=j div 2;
    while (j>1)and (compare(qtitle[j],qindex[j],qtitle[d],qindex[d])>0) do begin
      swap(j,d);
      j:=d;
      d:=j div 2
    end
  end;
  for i:=k downto 2 do begin
    swap(i,1);
    j:=1;
    d:=2*j;
    while (d+1<i) and ((compare(qtitle[j],qindex[j],qtitle[d],qindex[d])<0) or
          (compare(qtitle[j],qindex[j],qtitle[d+1],qindex[d+1])<0)) do
      if compare(qtitle[d],qindex[d],qtitle[d+1],qindex[d+1])>0 then begin
        swap(j,d);
        j:=d;
        d:=2*j
      end
      else begin
        swap(j,d+1);
        j:=d+1;
        d:=2*j
      end;
    if (d<i) and (compare(qtitle[j],qindex[j],qtitle[d],qindex[d])<0) then
      swap(j,d)
  end
end;

begin
  readln(b,s,r);
  readln(m,n);
  for i:=1 to n do
    readln(title[i],damount[i]);
  readln(k);
  for i:=1 to k do begin
    readln(qtitle[i],qindex[i]);
    qplace[i]:=i
  end;
  SortRequests;
  j:=1;
  for i:=1 to k do
    while j<=qtitle[i] do begin
      qtstart[j]:=i;
      j:=j+1
    end;
  while j<=m do begin
    qtstart[j]:=k+1;
    j:=j+1
  end;
  for i:=1 to m-1 do qtend[i]:=qtstart[i+1];
  qtend[m]:=k+1;
  p:=0;
  for i:=1 to m do tamount[i]:=0;
  for i:=1 to n do begin
    j:=title[i];
    while (qtstart[j]<qtend[j]) and
          (qindex[qtstart[j]]<=tamount[j]+damount[i]) do begin
      qans[qplace[qtstart[j]]]:=p+qindex[qtstart[j]]-tamount[j];
      qtstart[j]:=qtstart[j]+1
    end;
    p:=p+damount[i];
    tamount[j]:=tamount[j]+damount[i]
  end;
  for i:=1 to k do
    PrintPlace(qans[i]);
end.
```
:::
:::spoiler Код (C++, автор: [Zhdun](https://codeforces.com/profile/Zhdun))
```cpp
#include <bits/stdc++.h>
using namespace std;

int b, s, r;
int n, m;

map<int, vector<int>> mp;

void get_pos(int x) {
    int nom_rad = x / (b * s * r) + 1;
    x -= (nom_rad - 1) * (b * s * r);
    int nom_shkaf = x / (b * s) + 1;
    x -= (nom_shkaf - 1) * (b * s);
    int nom_polka = x / b + 1;
    x -= (nom_polka - 1) * b;
    if (!x) nom_polka--, x = b;
    if (!nom_polka) nom_polka = s, nom_shkaf--;
    if (!nom_shkaf) nom_shkaf = r, nom_rad--;
    cout << nom_rad << " " << nom_shkaf << " " << nom_polka << " " << x << endl;
}

int main() {
    cin >> b >> s >> r >> m >> n;
    int pos = 1;
    for (int i = 0; i < n; ++i) {
        int type, kol;
        cin >> type >> kol;
        for (int i = 0; i < kol; ++i) {
            mp[type].pb(pos);
            pos++;
        }
    }
    int q;
    cin >> q;
    for (int i = 0; i < q; ++i) {
        int type, nomber;
        cin >> type >> nomber;
        int x = mp[type][nomber - 1];
        get_pos(x);
    }
    return 0;
}
 
```
:::