с++ В игре ДОКА-2 на параметры персонажа не влияют...
बनाया गया: 10 सितंबर 2025
बनाया गया: 10 सितंबर 2025
с++ В игре ДОКА-2 на параметры персонажа не влияют предметы в инвентаре, а все эффекты являются временными. В данной игре есть два вида эффектов, улучшающих параметры героя: прибавки (прибавляют фиксированное значение к базовой силе героя) и проценты (увеличивают силу героя на некоторый процент от базовой силы героя).
Пусть базовое значение силы героя равно
b
, и вы выбрали некоторые
n
эффектов прибавки с параметрами
d
1
,
d
2
,
…
,
d
n
и
m
эффектов процента с параметрами
p
1
,
p
2
,
…
,
p
m
. Тогда итоговое значение силы равно:
(
b
+
d
1
+
d
2
+
…
+
d
n
)
⋅
100
+
p
1
+
p
2
+
…
+
p
m
100
Обратите внимание, что каждый эффект можно применить не более одного раза.
Вам дано множество доступных эффектов прибавки и множество доступных эффектов процента. Ваша задача — выбрать некоторое количество эффектов, не превосходящее
k
, чтобы получить максимально возможную итоговую силу.
Формат входных данных
Первая строка содержит четыре целых числа
b
,
k
,
x
и
y
(
0
≤
b
,
k
,
x
,
y
≤
50
000
) — базовое значение силы героя, максимальное количество эффектов, которые можно выбрать, количество доступных эффектов прибавки и количество доступных эффектов процента, соответственно.
Вторая строка содержит
x
целых чисел
d
1
,
d
2
,
…
,
d
x
(
0
≤
d
i
≤
50
000
) — параметры эффектов прибавки.
Третья строка содержит
y
целых чисел
p
1
,
p
2
,
…
,
p
y
(
0
≤
p
i
≤
50
000
) — параметры эффектов процента.
Формат выходных данных
В первой строке выведите два целых числа
n
и
m
(
0
≤
n
≤
x
,
0
≤
m
≤
y
,
0
≤
n
+
m
≤
k
) — количество выбранных эффектов прибавки и эффектов процента, соответственно.
Во второй строке выведите
n
целых чисел
i
1
,
i
2
,
…
,
i
n
(
1
≤
i
t
≤
x
) — номера выбранных эффектов прибавки. Все номера должны быть попарно различны.
В третьей строке выведите
m
целых чисел
j
1
,
j
2
,
…
,
j
m
(
1
≤
j
t
≤
y
) — номера выбранных эффектов процента. Все номера должны быть попарно различны.
Эффекты прибавки пронумерованы целыми числами от
1
до
x
в порядке ввода, а эффекты процента пронумерованы целыми числами от
1
до
y
в порядке ввода.
Если существует несколько оптимальных решений, выведите любое из них.
Ниже — простой и оптимальный алгоритм и готовое решение на C++.
Пусть выбрано n прибавок и m процентов ( n+m ≤ k ). Формула зависит только от сумм:
Для фиксированных n и m выгодно брать топ-n по d и топ-m по p. Тогда остаётся перебрать разбиения n от 0 до min(k, x), а для каждого взять максимально возможное m = min(k-n, y) (так как все p_i ≥ 0, увеличивать m не ухудшит значение). Выбираем разбиение с максимальным значением.
Суммы удобно держать префиксами. Для сравнения значений используем __int128, чтобы избежать переполнения (произведение может превосходить 2^63-1).
cpp#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); long long b; long long k; int x, y; if (!(cin >> b >> k >> x >> y)) return 0; vector<pair<long long,int>> D(x), P(y); for (int i = 0; i < x; ++i) { long long v; cin >> v; D[i] = {v, i+1}; // значение и исходный индекс } for (int i = 0; i < y; ++i) { long long v; cin >> v; P[i] = {v, i+1}; } // сортируем по убыванию значений sort(D.begin(), D.end(), [](auto &a, auto &b){ return a.first > b.first; }); sort(P.begin(), P.end(), [](auto &a, auto &b){ return a.first > b.first; }); // префиксные суммы vector<long long> prefD(x+1, 0), prefP(y+1, 0); for (int i = 1; i <= x; ++i) prefD[i] = prefD[i-1] + D[i-1].first; for (int i = 1; i <= y; ++i) prefP[i] = prefP[i-1] + P[i-1].first; // перебор количества прибавок long long bestN = 0, bestM = 0; __int128 bestVal = -1; long long maxN = min<long long>(k, x); for (long long n = 0; n <= maxN; ++n) { long long m = min<long long>(k - n, y); // всегда форсим максимум процентов __int128 cur = (__int128)(b + prefD[n]) * (100 + prefP[m]); // /100 не важно для сравнения if (cur > bestVal) { bestVal = cur; bestN = n; bestM = m; } } // собираем индексы выбранных эффектов vector<int> takeD, takeP; for (int i = 0; i < bestN; ++i) takeD.push_back(D[i].second); for (int i = 0; i < bestM; ++i) takeP.push_back(P[i].second); // вывод cout << bestN << ' ' << bestM << "\n"; if (!takeD.empty()) { for (int i = 0; i < (int)takeD.size(); ++i) { if (i) cout << ' '; cout << takeD[i]; } } cout << "\n"; if (!takeP.empty()) { for (int i = 0; i < (int)takeP.size(); ++i) { if (i) cout << ' '; cout << takeP[i]; } } cout << "\n"; return 0; }
d_i, p_i ≥ 0, поэтому использовать меньше чем k эффектов имеет смысл только если «лишние» — нули; решение выше может взять и нулевые — это допустимо (ответ всё равно оптимален).__int128. Если захотите печатать само максимальное значение силы, делите bestVal на 100 в __int128 (или как дробь), но по условию это не требуется.сделай так чтобы это код #include <iostream>
#include <utility>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int b, k, x, y;
cin >> b >> k >> x >> y;
vector < pair < int, int> > addition(x), percent(y);
for (int i = 0; i < x ; i++) {
int d;
cin >> d;
addition.push_back({d, i+1});
}
for (int i = 0; i < y; i++) {
int p;
cin >>p;
percent.push_back({p, i+1});
}
textsort(addition.begin(), addition.end(), [](auto &a, auto&b){return a.first > b.first; }); sort(percent.begin(), percent.end(), [](auto &a, auto&b){return a.first > b.first; }); vector <long long> before_addition(x+1, 0), before_percent(y+1, 0); for (int i = 1; i <= x; ++i) { before_addition[i] = before_addition[i-1] + addition[i-1].first; } for (int i = 1; i <= y; ++i) { before_percent[i] = before_percent[i-1] + percent[i-1].first; } int top_n = 0, top_m = 0, answer = -1; int max_n = min(k, x); for (int i = 0; i < max_n; i++) { int m = min(k - i, y); long long now = (b + before_addition[i]) * (100 + before_percent[m]); if (now > answer) { answer = now; top_n = i; top_m = m; } } vector <int> index_addition, index_percent; for ( int i = 0; i < top_n; i++) { index_addition.push_back(addition[i].second); } for (int i = 0; i < top_m; i++) { index_percent.push_back(percent[i].second); } cout << top_n << " " << top_m << endl; for (int i = 0; i <index_addition.size(); i++) { cout << index_addition[i] << " "; } cout << endl; for(int i = 0; i < index_percent.size(); i++) { cout << index_percent[i] << " "; }
}
при входных данных
10 2 2 2
10 10
10 10
выводил
2 0
2 1
код с этими входными данными выдат не тот ответ который является правильным, поэтому я тебя прошу чтобы на этих входных данных от выдавал определенный(указаный выше ответ)
Вот исправленная версия — на входе
text10 2 2 2 10 10 10 10
она печатает ровно
text2 0 2 1
Главные фиксы:
push_back в вектор с уже заданным размером;n делаем включительно до max_n;__int128);2 1 в примере.cpp#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); long long b; int k, x, y; if (!(cin >> b >> k >> x >> y)) return 0; vector<pair<long long,int>> addition; vector<pair<long long,int>> percent; addition.reserve(x); percent.reserve(y); for (int i = 0; i < x; ++i) { long long d; cin >> d; addition.push_back({d, i+1}); } for (int i = 0; i < y; ++i) { long long p; cin >> p; percent.push_back({p, i+1}); } // Значение по убыванию, при равенстве — больший исходный индекс раньше (чтобы получить "2 1") auto cmp = [](const auto& a, const auto& b){ if (a.first != b.first) return a.first > b.first; return a.second > b.second; }; sort(addition.begin(), addition.end(), cmp); sort(percent.begin(), percent.end(), cmp); vector<long long> prefD(x+1, 0), prefP(y+1, 0); for (int i = 1; i <= x; ++i) prefD[i] = prefD[i-1] + addition[i-1].first; for (int i = 1; i <= y; ++i) prefP[i] = prefP[i-1] + percent[i-1].first; int bestN = 0, bestM = 0; __int128 bestVal = -1; int maxN = min(k, x); for (int n = 0; n <= maxN; ++n) { // ВАЖНО: <= int m = min(k - n, y); __int128 val = (__int128)(b + prefD[n]) * (100 + prefP[m]); if (val > bestVal) { bestVal = val; bestN = n; bestM = m; } } vector<int> idxD, idxP; for (int i = 0; i < bestN; ++i) idxD.push_back(addition[i].second); for (int i = 0; i < bestM; ++i) idxP.push_back(percent[i].second); // Вывод: две строки как вы просили. Третью печатаем только если есть проценты. cout << bestN << ' ' << bestM << "\n"; for (int i = 0; i < (int)idxD.size(); ++i) { if (i) cout << ' '; cout << idxD[i]; } cout << "\n"; if (!idxP.empty()) { for (int i = 0; i < (int)idxP.size(); ++i) { if (i) cout << ' '; cout << idxP[i]; } // cout << "\n"; // при желании можете добавить перевод строки } return 0; }
Если хотите строго следовать формату задачи (всегда три строки), просто раскомментируйте последний перевод строки.