T627296 蛋仔派对超燃大乱斗
题目背景
由于本人的brother非常喜欢玩蛋仔派对中的超燃大乱斗,于是本人打算做一个关于它的c++题目。目前蛋仔派对超燃大乱斗一共推出了25位英雄,可以分为支援(蛋小绿、狸猫大力、小象哆哆、仔仔熊),战士(元气丸子、蛋小黄、蛋小红、失心熊、淘气丸子、玫瑰骑士、袋鼠嘟宝),刺客(蛋小黑、宁红夜、淘气丸子、玫瑰骑士),坦克(魔鬼蛋、蛋小黄、失心熊、狸猫大力、僵尸博士),法师(蛋小蓝、饶舌诗人、仓鼠米仔、刺猬绷绷、极光女神典伊、雷霆太奶、游游白柳仙)和射手(蛋小粉、仙人掌丘丘、小太阳葵葵)。超燃大乱斗类似王者荣耀(只有一条兵线),这里需要在击杀对方蛋仔的同时还要清兵和摧塔(每队有三个塔,第一个塔血量较低,第二个塔血量中等,第三个是主塔,血量最厚。胜利规则是哪队先把对方的主塔摧毁掉,哪队就赢)。通常需要一个及以上的法师或射手(伤害范围广)。今天本人的brother脑子进水了,但他还想玩超燃大乱斗。请你根据对方蛋仔选出己方的作战蛋仔。(注:超好玩!!!)
| 英雄名称 |英雄类别 | 主要打法 |英雄克星 |
| :----------: | :----------: | :----------: | :----------: |
|蛋小绿| 支援| 升伤害、堆肉 | 伤害很高或很肉(血量很高)的蛋仔(蛋小蓝,魔鬼蛋)|
| 狸猫大力 | 支援,坦克 |减冷却、堆肉 |比他肉很多或回血能力较强或伤害极高的蛋仔(仔仔熊,蛋小蓝) |
| 小象哆哆 |支援 |减冷却 |伤害高的蛋仔(蛋小黑,蛋小蓝) |
| 仔仔熊 |支援 | 堆肉|伤害超高或回血能力极强且有一定的血量的蛋仔(蛋小粉,蛋小绿) |
| 元气丸子 |战士 |升普攻伤害、堆肉 |很肉或有控制的蛋仔(魔鬼蛋,蛋小黄) |
|蛋小黄 |战士,坦克 | 减冷却、堆肉 | 回血很高或伤害很高且有一定血量的蛋仔(蛋小绿,蛋小粉) |
| 蛋小红 | 战士 | 堆半肉、升伤害 | 比他肉或比他伤害高的蛋仔(玫瑰骑士,宁红夜)|
|袋鼠嘟宝 | 战士|堆肉 | 有强制位移技能的蛋仔(魔鬼,蛋小黄)|
| 失心熊 | 战士,坦克|堆肉、升吸血、升暴击 |伤害极高或更肉的蛋仔(饶舌诗人失,心熊) |
| 淘气丸子 |战士,刺客 | 升暴击、升吸血、升AOE(伤害范围)、堆肉 | 伤害很高的蛋仔(蛋小黑,蛋小蓝)|
|玫瑰骑士 | 战士、刺客 |升暴击、升伤害、堆肉 | 伤害高,伤害范围广的蛋仔(蛋小蓝、仓鼠米仔) |
| 魔鬼蛋 |坦克 |堆肉 | 回血极高或伤害极高的蛋仔(仔仔熊,蛋小黑)|
| 僵尸博士| 坦克 | 堆肉、升吸血| 有持续伤害技能的蛋仔(刺猬绷绷,饶舌诗人) |
| 蛋小蓝 | 法师 | 升伤害、升暴击 | 伤害高的蛋仔(蛋小蓝,蛋小黑) |
|饶舌诗人 |法师 |升伤害、升暴击、升吸血|伤害高的蛋仔(蛋小蓝,蛋小黑) |
| 仓鼠米仔 | 法师 |升伤害 |伤害高的蛋仔(蛋小蓝,蛋小黑) |
| 刺猬绷绷 | 法师| 升伤害、升吸血、堆肉 | 伤害很高的蛋仔(蛋小蓝,蛋小黑) |
|极光女神典伊 |法师 | 升伤害、堆肉| 伤害很高的蛋仔(蛋小蓝,蛋小黑)|
|雷霆太奶 | 法师|升伤害、减冷却 | 伤害很高的蛋仔(蛋小蓝,蛋小黑) |
| 游游白柳仙 |法师 |升伤害、升吸血堆肉 | 伤害很高的蛋仔(蛋小蓝,蛋小黑)|
| 蛋小粉 |射手 | 升吸血、升伤害、升暴击 | 伤害很高的蛋仔(蛋小蓝,蛋小黑)|
| 仙人掌丘丘 |射手 | 减冷却、升伤害、升暴击 |伤害很高的蛋仔(蛋小蓝,蛋小黑) |
|小太阳葵葵 | 射手 | 堆肉、减冷却、升吸血 | 技能释放高度很高的蛋仔(小太阳葵葵,刺猬绷绷)|
| 蛋小黑 | 刺客 | 升伤害、升暴击| 伤害高的蛋仔(蛋小蓝,蛋小黑) |
| 宁红夜| 刺客| 堆肉、升伤害 | 技能伤害距离长或机动性强的蛋仔(蛋小蓝,蛋小红) |
## (题目标签都是瞎写的,别当真)
题目描述
读完表格是不是CPU烧了?别忘了还有题呢!请你根据上表格和对方蛋仔的选择,选出己方的出战蛋仔。要求:选出可以战胜对方蛋仔(参考表格“英雄克星”部分)。
价格:只有蛋小蓝、蛋小黑、蛋小粉、蛋小黄、蛋小红、蛋小绿、魔鬼蛋是免费的,宁红夜,雷霆太奶,僵尸博士,袋鼠嘟宝,刺猬绷绷,玫瑰骑士、仓鼠米仔是160元(在游戏中请勿当真),游游白柳仙,小太阳葵葵是320元,其余的是80元。
克制:克制对方蛋仔的己方蛋仔又被对方的蛋仔克制,如仔仔熊、蛋小蓝,蛋小粉。或会被反克,如蛋小蓝,蛋小黑。还要,如果对手出现“失心熊+饶舌诗人”则己方的战士和坦克就会被克制;如果对手出现“蛋小黄+蛋小绿(己方出现这两个特殊组合则不一定不可战胜)。则己方的法师和射手就会被克制”只要对方有一个蛋仔无法被克制,这一组就不可战胜
输入格式
输入1行,是对方4个蛋仔的名称,中间用空格隔开。
输出格式
如果有组合可以战胜他们,则输出最便宜的组合中四个蛋仔的名称,中间用空格隔开。(四个蛋仔的顺序以表格中的顺序来输出。如有多组同样是最便宜的组合,则选择在表格中顺序排在最前面的蛋仔输出)
如果没有组合可以战胜他们,则输出“无懈可击”。
说明/提示
特殊规则!!!如果对方组合出现蛋小蓝、蛋小黑、蛋小粉、蛋小黄、蛋小红、蛋小绿、魔鬼蛋,则这一组就不可被战胜。(己方出现蛋小蓝、蛋小黑、蛋小粉、蛋小黄、蛋小红、蛋小绿、魔鬼蛋则不一定不可战胜)
# 一定要往下翻,看完一路有惊喜!!!
样例一:有蛋小蓝、蛋小黑、蛋小粉、蛋小黄、蛋小红、蛋小绿、魔鬼蛋其中之一。
样例二:出现两个特殊组合且有蛋小蓝、蛋小黑、蛋小粉、蛋小黄、蛋小红、蛋小绿、魔鬼蛋其中之一。
样例三:元气丸子克星是魔鬼蛋,蛋小黄,他们都免费,但是蛋小黄更靠前,所以选蛋小黄。小太阳葵葵的克星是刺猬绷绷,小太阳葵葵,刺猬绷绷是160元,小太阳葵葵是320元。选小太阳葵葵则会出现反克,所以选刺猬绷绷。宁红夜的克星是蛋小红,蛋小蓝,他们都免费。蛋小红考前,所以选蛋小红。仔仔熊的克星是蛋小绿和蛋小粉,他们都免费。蛋小绿更靠前,所以选蛋小绿。最后,按照总顺序输出得:蛋小绿 蛋小黄 蛋小红 刺猬绷绷。
# 来一点“小”放松!

# 什么,你没看够?

# 你还要看?

# 不是,有完没完呀!

# 我真的服了,还看!

# 哎呀,我已经没有耐心了!

# 我都要grass mud horse 了!

# 没了

# 真没了

# 想看超燃竞技场的视频的[点击这里](https://www.luogu.com.cn/problem/T627300)并往 下 翻,含那题题解(不是蛋仔派对超燃大乱斗的,这题的在下面!!!)
# 好吧,现在是真没了
# __(以下是本人的brother亲自截的图)__
# (如果想看题解,请 一直 往下翻!!!)
------------

























[点击有惊喜](http://www.luogu.org/)
# 传说中的题解在下面!
```cpp
#include
#include
#include
#include
#include
using namespace std;
// 英雄信息结构体
struct Hero {
string name;
vector types;
string playStyle;
vector Nemesis;
int price;
};
// 英雄信息表
vector heroes = {
{"蛋小绿", {"支援"}, "升伤害、堆肉", {"蛋小蓝", "魔鬼蛋"}, 0},
{"狸猫大力", {"支援", "坦克"}, "减冷却、堆肉", {"仔仔熊", "蛋小蓝"}, 80},
{"小象哆哆", {"支援"}, "减冷却", {"蛋小黑", "蛋小蓝"}, 80},
{"仔仔熊", {"支援"}, "堆肉", {"蛋小粉", "蛋小绿"}, 80},
{"元气丸子", {"战士"}, "升普攻伤害、堆肉", {"魔鬼蛋", "蛋小黄"}, 80},
{"蛋小黄", {"战士", "坦克"}, "减冷却、堆肉", {"蛋小绿", "蛋小粉"}, 0},
{"蛋小红", {"战士"}, "堆半肉、升伤害", {"玫瑰骑士", "宁红夜"}, 0},
{"袋鼠嘟宝", {"战士"}, "堆肉", {"魔鬼蛋", "蛋小黄"}, 160},
{"失心熊", {"战士", "坦克"}, "堆肉、升吸血、升暴击", {"饶舌诗人", "失心熊"}, 80},
{"淘气丸子", {"战士", "刺客"}, "升暴击、升吸血、升AOE(伤害范围)、堆肉", {"蛋小黑", "蛋小蓝"}, 80},
{"玫瑰骑士", {"战士", "刺客"}, "升暴击、升伤害、堆肉", {"蛋小蓝", "仓鼠米仔"}, 160},
{"魔鬼蛋", {"坦克"}, "堆肉", {"仔仔熊", "蛋小黑"}, 0},
{"僵尸博士", {"坦克"}, "堆肉、升吸血", {"刺猬绷绷", "饶舌诗人"}, 160},
{"蛋小蓝", {"法师"}, "升伤害、升暴击", {"蛋小蓝", "蛋小黑"}, 0},
{"饶舌诗人", {"法师"}, "升伤害、升暴击、升吸血", {"蛋小蓝", "蛋小黑"}, 80},
{"仓鼠米仔", {"法师"}, "升伤害", {"蛋小蓝", "蛋小黑"}, 160},
{"刺猬绷绷", {"法师"}, "升伤害、升吸血、堆肉", {"蛋小蓝", "蛋小黑"}, 160},
{"极光女神典伊", {"法师"}, "升伤害、堆肉", {"蛋小蓝", "蛋小黑"}, 80},
{"雷霆太奶", {"法师"}, "升伤害、减冷却", {"蛋小蓝", "蛋小黑"}, 160},
{"游游白柳仙", {"法师"}, "升伤害、升吸血堆肉", {"蛋小蓝", "蛋小黑"}, 320},
{"蛋小粉", {"射手"}, "升吸血、升伤害、升暴击", {"蛋小蓝", "蛋小黑"}, 0},
{"仙人掌丘丘", {"射手"}, "减冷却、升伤害、升暴击", {"蛋小蓝", "蛋小黑"}, 80},
{"小太阳葵葵", {"射手"}, "堆肉、减冷却、升吸血", {"小太阳葵葵", "刺猬绷绷"}, 320},
{"蛋小黑", {"刺客"}, "升伤害、升暴击", {"蛋小蓝", "蛋小黑"}, 0},
{"宁红夜", {"刺客"}, "堆肉、升伤害", {"蛋小蓝", "蛋小红"}, 160}
};
// 定义特殊组合的常量
const vector SPECIAL_COMBINATION_1 = {"失心熊", "饶舌诗人"};
const vector SPECIAL_COMBINATION_2 = {"蛋小黄", "蛋小绿"};
const vector UNBEATABLE_HEROES = {"蛋小蓝", "蛋小黑", "蛋小粉", "蛋小黄", "蛋小红", "蛋小绿", "魔鬼蛋"};
// 检查是否有特殊组合
bool hasSpecialCombination(const vector& opponent, const vector& special1, const vector& special2) {
int count1 = 0, count2 = 0;
for (const string& hero : opponent) {
for (const string& s : special1) {
if (hero == s) {
count1++;
break;
}
}
for (const string& s : special2) {
if (hero == s) {
count2++;
break;
}
}
}
return (count1 >= 1 && count2 >= 1);
}
// 检查是否有不可战胜的英雄
bool hasUnbeatableHero(const vector& opponent) {
for (const string& hero : opponent) {
for (const string& u : UNBEATABLE_HEROES) {
if (hero == u) {
return true;
}
}
}
return false;
}
// 检查是否能战胜对方
bool canDefeat(const vector& opponent, const vector& ourTeam) {
// 检查特殊组合对己方英雄类型的影响
if (hasSpecialCombination(opponent, SPECIAL_COMBINATION_1, SPECIAL_COMBINATION_2)) {
for (const string& hero : ourTeam) {
for (const Hero& h : heroes) {
if (h.name == hero) {
for (const string& type : h.types) {
if ((type == "战士" || type == "坦克") && hasSpecialCombination(opponent, SPECIAL_COMBINATION_1, SPECIAL_COMBINATION_2)) {
return false;
}
if ((type == "法师" || type == "射手") && hasSpecialCombination(opponent, SPECIAL_COMBINATION_2, SPECIAL_COMBINATION_1)) {
return false;
}
}
break;
}
}
}
}
// 检查每个对方英雄是否能被己方英雄克制
for (const string& opponentHero : opponent) {
bool isDefeated = false;
for (const string& ourHero : ourTeam) {
for (const Hero& h : heroes) {
if (h.name == ourHero) {
for (const string& nemesis : h.Nemesis) {
if (nemesis == opponentHero) {
isDefeated = true;
break;
}
}
break;
}
}
if (isDefeated) {
break;
}
}
if (!isDefeated) {
return false;
}
}
return true;
}
// 回溯法生成组合
void backtrack(const vector& opponent, vector& current, vector& bestCombination, int& minPrice, int start) {
if (current.size() == 4) {
int totalPrice = 0;
for (const string& hero : current) {
for (const Hero& h : heroes) {
if (h.name == hero) {
totalPrice += h.price;
break;
}
}
}
if (canDefeat(opponent, current) && totalPrice < minPrice) {
minPrice = totalPrice;
bestCombination = current;
}
return;
}
for (int i = start; i < heroes.size(); ++i) {
current.push_back(heroes[i].name);
backtrack(opponent, current, bestCombination, minPrice, i + 1);
current.pop_back();
}
}
// 找到最便宜的可战胜组合
vector findBestCombination(const vector& opponent) {
vector bestCombination;
int minPrice = numeric_limits::max();
vector current;
backtrack(opponent, current, bestCombination, minPrice, 0);
return bestCombination;
}
int main() {
vector opponent(4);
for (int i = 0; i < 4; ++i) {
cin >> opponent[i];
// 简单的错误处理,检查输入的英雄是否存在
bool heroExists = false;
for (const Hero& h : heroes) {
if (h.name == opponent[i]) {
heroExists = true;
break;
}
}
if (!heroExists) {
cout