Сабж
прошел сегодня на
задачах школьного чемпионата, что означало простые и короткие задачи. Победил
renatm без единого бревна через 43 минуты после начала. Я финишировал 4-м (внезапно сеть стала говорить Reply from 81.20.20.4: TTL expired in transit.).
А трусишка
udpn предпочел смотреть мультики.
AНайти минимальное число квадратов натуральных чисел, дающих в сумме N.
Задача на ДП. Кроме того, можно вспомнить
теорему Гильберта-Варинга, которая, в частности, утверждает, что любое натуральное число можно представить в виде суммы
не более 4 квадратов.
const int M = 2010;
int dp[M];
memset(dp, 0, sizeof(dp));
for (int i = 1; i * i < M; ++i) dp[i * i] = 1;
for (int i = 2; i <= 4; ++i) {
for (int j = 1; j < M; ++j) if (dp[j] == i-1) {
for (int k = 1; k * k + j < M; ++k) {
if (dp[k * k + j] == 0) {
dp[k * k + j] = i;
}
}
}
}
int n;
cin >> n;
cout << dp[n] << endl;
BВ клеточном квадрате 2009x2009 в ячейке (x;y) завелся вирус, который может перемещаться только в окрестности фон Неймана (4 клетки) и не может дважды посещать одну ячейку. Найти минимальное число клеток, которые он посетит, прежде чем будет обездвижен.
Немного порисовав, можно понять, что уголок будет выглядеть примерно так:
688888
688888
678888
567888
486788
645666
и написать соответствующий ему код. Если код будет не соответствовать, можно получить +3, как у меня.
const int M = 2009;
int x, y;
cin >> x >> y;
x = min(x, M-x+1);
y = min(y, M-y+1);
if (x == 1 && y == 2 || x == 2 && y == 1) cout << 4;
else if (x == 1 && y == 3 || y == 1 && x == 3) cout << 5;
else if (x == 1 || y == 1 || x + y == 5) cout << 6;
else if (x + y == 6) cout << 7;
else cout << 8;
cout << endl;
CДаны числа 1..N. Игрок А ходом забирает любое простое число, игрок Б любой палиндром. Если один игрок не может сделать ход, другой забирает все оставшиеся. Сколько заберет А при оптимальной игре с обоих сторон?
Оптимальной стратегией с обеих сторон является брать сначала простые палиндромы. Выигрыш зависит от того, кому дольше хватит чисел. Достаточно посчитать количество простых палиндромов, просто простых чисел и просто палиндромов, после чего выписать ответ.
Функции ispali и isprime не приводятся ввиду их очевидности.
int n;
cin >> n;
int pp = 0, pr = 0, pa = 0;
for (int i = 1; i <= n; ++i) {
bool prime = isprime(i), pali = ispali(i);
if (prime && pali) ++pp;
else if (prime) ++pr;
else if (pali) ++pa;
}
if (pp / 2 + pa < pp / 2 + pp % 2 + pr) cout << n - (pp / 2 + pa) << endl;
else cout << (pp / 2 + pp % 2 + pr) << endl;
DКоординатами углов (≤2009) заданы два целочисленных прямоугольника 1 и 2. Найти площадь 1−2.
Небольшие значения координат позволяют решить задачу тупым моделированием.
char a[2010][2010];
const int M = 2009;
memset(a, 0, sizeof(a));
int xl1, xr1, yl1, yr1, xl2, xr2, yl2, yr2;
cin >> xl1 >> xr1 >> yl1 >> yr1 >> xl2 >> xr2 >> yl2 >> yr2;
for (int i = xl1; i < xr1; ++i) for (int j = yl1; j < yr1; ++j) a[i][j] = 1;
for (int i = xl2; i < xr2; ++i) for (int j = yl2; j < yr2; ++j) a[i][j] = 2;
int res = 0;
for (int i = xl1; i < xr1; ++i) for (int j = yl1; j < yr1; ++j) if (a[i][j] == 1) ++res;
cout << res;
EИз N монет (5 ≤ N ≤ 1000) K лежат решкой вверх. За шаг можно перевернуть любые 5. Можно ли повернуть все монеты одной стороной вверх?
Можно подумать, а можно реализовать простое ДП [решек] = шагов.
int n, k;
cin >> n >> k;
vector
dp(n + 1);
dp[k] = 1;
bool was = true;
for (int step = 2; was; ++step) {
was = false;
for (int i = 0; i <= n; ++i) if (dp[i] == step - 1) {
for (int j = 0; j <= 5; ++j) {
if (i >= j && n - i >= 5 - j) {
int newk = i - j + 5 - j;
if (dp[newk] == 0) {
dp[newk] = step;
was = true;
}
}
}
}
}
if (dp[0] || dp[n]) cout << "YES" << endl;
else cout << "NO" << endl;
F
В N! (N > 5, не больше 100 цифр) одна цифра заменена символом ?. Написать это число без ?.
Простейшее решение - наглый хардкод. Легко догадаться, что все N! при N>5 отличаются длиной, а сам список факториалов без труда выдаст Maple.
string s[] = { /* Хардкод */ };
string a;
cin >> a;
int i;
for (i = 0; a.length() != s[i].length(); ++i);
cout << s[i] << endl;
G
Найти минимальное число разрезов, нужных для разделения прямоугольника NxM на отдельные клетки (прямоугольники можно перемещать).
Просто сумма округленных вверх двоичных логарифмов.
int n, m;
cin >> n >> m;
cout << int(ceil(log((double) n) / log(2.0)) + ceil(log((double) m) / log(2.0))) << endl;
А если кто-то еще не успел ознакомиться с потрясающим Wolfram Alpha (хочу у них работать, хнык) или с изумительной 4K PC демкой elevated by Rgba [web] & TBC (видео, потому что машина нужна беспощадно суровая) - самое время это сделать.