Codeforces 371 Проблема C
Постановка задачи
Вам дан рецепт бургера в виде строки, состоящей из Хлеба(B), Колбасы(S) и Сыра(C), например, рецепт «ВSCBS» представляет собой гамбургер, в котором ингредиенты идут снизу вверх как хлеб, колбаса, сыр, хлеб и еще раз колбаса.
Теперь у вас есть магазин с неограниченным запасом этих трех ингредиентов со стоимостью Pb (стоимость хлеба), Ps (стоимость колбасы), Pc (стоимость сыра). И на вашей кухне у вас есть запас этих предметов с количеством Nb (количество хлеба на складе), Ns и Nc. А у тебя в кармане ррублей.
Выведите максимальное количество гамбургеров, которое вы можете приготовить.
Решение
Если возможно сделать X гамбургеров. Тогда для всех k ‹ X мы также можем приготовить k бургеров.
Теперь, чтобы проверить, возможно ли сделать X бургеров, нам нужно создать функцию, которая проверяет стоимость приготовления X бургеров и возвращает true, если она ≤ денег, которые у нас есть. Вызовите эту функцию canMake(X)
Таким образом, нам нужно рассчитать необходимый сыр, необходимый хлеб, необходимую колбасу, которые равны X * (количество ингредиентов в рецепте) - (количество ингредиентов, которые у нас есть на складе), здесь ингредиент может быть = [сыр, колбаса, хлеб]
Тогда общая стоимость будет равна (neededIngredient) * Цена ингредиента.
вернуть totalCost ≤ Деньги в кармане, что является истинным или ложным.
Теперь мы можем перебирать все значения от X=0, увеличивая их на 1, пока не найдем первое значение X, которое дает canMake(X) как ложное. Это означает, что X-1 является ответом.
Это порядка O(n²), что довольно медленно. При наблюдении вывод canMake(X) таков, что мы можем выполнить двоичный поиск ответа.
Вот пример кода, который вы можете отправить
#include <bits/stdc++.h> using namespace std; #define mp make_pair #define pb push_back #define lb lower_bound #define up upper_bound #define vll vector<ll> #define G vector<vll > #define gg vector<int> #define F first #define S second #define pll pair<ll,ll> #define pii pair<int,int> #define RFOR(i,a,b) for(int i=a;i>=b;i--) #define FOR(i,a,b) for(int i=a;i<=b;i++) #define endl '\n' #define clr(a) memset(a,0,sizeof(a)) #define all(x) x.begin(),x.end() #define rll read_ll(); #define gc getchar #define pc putchar typedef long long ll; template<class A> ostream& operator<<(ostream& out, const vector<A> &a){ out<<"[";for(auto it=a.begin();it!=a.end();it++){if(it!=a.begin())out<<",";out<<*it;}cout<<"]"; return out;} template<class T> inline T lcm(T a,T b){ return a/gcd(a,b)*b; } template<typename T> void debug(T first) { cout << first << "\n"; } template<typename T, typename... Args> void debug(T first, Args... args) { cout << first << " "; debug(args...); } ll read_ll(){char c=gc();while((c<'0'||c>'9')&&c!='-')c=gc();ll ret=0;int neg=0;if(c=='-')neg=1,c=gc();while(c>='0'&&c<='9'){ret=10*ret+c-48;c=gc();}return neg?-ret:ret;} string sw; ll pb, ps, pcc, nb, ns, nc, money; ll cb, cs, cc; bool ok(ll need) { ll needb = max(need*cb-nb,0LL), needs = max(0LL,need*cs-ns), needc = max(0LL,need*cc-nc); ll total = needb*pb + needs*ps + needc*pcc; return total <= money; } int main() { cin>>sw>>nb>>ns>>nc>>pb>>ps>>pcc>>money; for(auto c : sw) { if(c == 'B') cb++; else if(c == 'S') cs++; else cc++; } ll l = 0, r = 1e15; while((r-l)>1) { ll m = l+(r-l)/2; if(ok(m)) l = m; else r = m-1; } if(ok(r)) cout<<r; else cout<<l; return 0; }