Матч
409, Палка (Stick)
Дивизион 2,
Уровень 1
У Джона есть палка длиной
1. Джон суммирует длины имеющихся
у него кусков (изначально имеется один кусок длины
·
Джон выбирает кусок наименьшей длины и ломает его пополам;
·
Если после выбрасывания одной из половинок сумма оставшихся кусков не
станет меньше х, то выбросить ее;
2. Джон склеивает имеющиеся у
него куски.
Вычислить количество кусков,
которое Джон будет склеивать на втором шаге алгоритма.
Класс: Stick
Метод: int
pieces(int x)
Ограничения: 1 £ x £ 64.
Вход. Длина требуемой палки х.
Выход. Количество кусков, которое Джон будет склеивать на втором
шаге алгоритма.
Пример входа
x |
32 |
48 |
23 |
Пример выхода
1
2
4
РЕШЕНИЕ
элементарные вычисления
Задачу можно решить двумя
способами:
1. Моделирование процесса разлома
палок. Палку наименьшей длины будем находить в результате сортировки.
Суммировать длины палок будем при помощи функции accumulate.
2. Можно заметить, что длины
получающихся палок в процессе разлома являются степенями 2. Поэтому ответом
будет количество единиц в бинарном представлении числа х. Операция x = x & (x – 1) уничтожает последнюю единицу в бинарном представлении числа х.
ПРОГРАММА
#include <cstdio>
#include <vector>
#include <numeric>
#include <algorithm>
using namespace std;
vector<int>
v(1,64);
class Stick
{
public:
int pieces(int x)
{
int sum, v0;
while((sum =
accumulate(v.begin(),v.end(),0)) > x)
{
sort(v.begin(),v.end());
v0 = v[0]; v[0] = v0 / 2;
if (sum - v[0] < x)
v.push_back(v[0]);
}
return v.size();
}
};
Реализация
функции pieces через подсчет битов:
#include <stdio.h>
class Stick
{
public:
int pieces(int x)
{
int res=0;
for(; x; x = x & (x - 1)) res++;
return res;
}
};