# Разбор задач 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; } ``` :::