信科每年必备项目。写了一周,满打满算有三天放弃其他科写这个代码。
居然只是第三个,终极版本会写的有多艰难我已经预料。
AC的那一刻感觉真的体会到了“范进中举”的快感。
学弟学妹们大概也会上网搜索,故放我自己不够精致的代码在此,也算做个记录。
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
//对dragon ninja iceman lion wolf分别用0,1,2,3,4代替
int Time;//时间
void putTime(int n)
{
int h = n / 60;
int m = n % 60;
if (h >= 100)
cout << h << ":";
else if (h >= 10)
cout << 0 << h << ":";
else
cout << "00" << h << ":";
if (m >= 10)
cout << m << " ";
else
cout << 0 << m << " ";
}//输出时间
int value[5] = { 0 };//0,1,2,3,4武士制造需要的生命元数量
int gongji[5];//0,1,2,3,4武士的攻击力
int MAX = 0;//记录最多轮数,防止互相攻击伤害不了进入死循环
int N;//N个城市
int K;//loyalty要减少的量
//司令部设置一个类
class Head {
public:
int color;//0表示红色1表示蓝色
char colorname[5], oppname[5];
int warriornum;//制作武士顺序
int initiallife;//生命元总量
int zone;//司令部地址
Head() {}
Head(int n, int life)
{
color = n;
initiallife = life;
if (n == 0) {
zone = 0;
strcpy(colorname, "red");
strcpy(oppname, "blue");
}
else {
zone = N + 1;
strcpy(colorname, "blue");
strcpy(oppname, "red");
}
}
void talk()
{
putTime(Time);
cout << initiallife << " elements in " << colorname << " headquarter" << endl;
}//报告生命元数量
};
//定义一个武器总类
class Weapon {
public:
int gongjili;
int usingTime = 0;//使用次数
int haoma;//编号就已经代表了它的类了,共三类
char wuqiname[3][7] = { "sword","bomb","arrow" };
Weapon(int n)
{
haoma = n;
}
};
//首先的武士类总定义
class Warriors {
public:
int variety;//0,1,2,3,4代表了类型
int bianhao;
int lifevalue;
int attack;//攻击力
Weapon* wuqi[10];//最多十个武器,这是武士类所能携带的
int wuqinum[3] = { 0 };//记录武器分别的数目
Head siling;//0表示红司令,1表示蓝司令
int location = 0;//所在城市的位置
int wuqitotal = -1;//武器的总数,不超过9(记录数组下标)-1相当于没有了
int nowusing;//正在用的武器记录
char warriorname[5][10] = { "dragon","ninja","iceman","lion","wolf" };
bool isdie()
{
if (lifevalue <= 0)
return true;
else
return false;
}//是死了吗
virtual void aftergo()
{
if (lifevalue > 0) {
if (location == 0||location == N + 1) {
if (isconquer())
{
putTime(Time);
cout << siling.colorname <<" "<< warriorname[variety] <<" "<< bianhao << " reached " << siling.oppname << " headquarter with " << lifevalue << " elements and force " << attack << endl;
putTime(Time);
cout << siling.oppname << " headquarter was taken" << endl;
}
}
else
{
putTime(Time);
cout << siling.colorname << " " << warriorname[variety] << " " << bianhao << " marched to city " << location << " with " << lifevalue << " elements and force " << attack << endl;
}
}
}//前进一步之后的汇报
virtual void show()
{
if (lifevalue > 0 && location <= N + 1) {
wuqinum[0] = 0, wuqinum[1] = 0, wuqinum[2] = 0;
for (int i = 0; i <= wuqitotal; i++)
{
if(wuqi[i]!=NULL)
wuqinum[wuqi[i]->haoma]++;
}
putTime(Time);
cout << siling.colorname << " " << warriorname[variety] << " " << bianhao << " has " << wuqinum[0] << " sword " << wuqinum[1] << " bomb " << wuqinum[2] << " arrow and " << lifevalue << " elements" << endl;
}
}//武士报告情况
bool isconquer()
{
if (location == N + 1 - siling.zone)
return true;
return false;
}
virtual void making(int n, Head* m) {}
virtual void goahead() {}//注意只有活着的士兵才会往前走
virtual void runaway() {}//逃跑
virtual void bisaizhunbei(Warriors* t, int loc) {}//wolf会抢对方编号最小的武器
Warriors() {}
virtual void offence(Warriors& s)
{
if (wuqitotal >= 0) {
int jiluhunt = 0;
while (wuqi[nowusing] == nullptr && jiluhunt <= 5)
{
nowusing++;
if (nowusing >= wuqitotal + 1)
{
nowusing = 0;
}
jiluhunt++;
}
if (wuqi[nowusing] == nullptr)
wuqitotal = -1;//没有武器可用的情况下
else
{
int sword = attack * 2 / 10;
int bomb = attack * 4 / 10;
int bombfantan = bomb / 2;
int arrow = attack * 3 / 10;
if (wuqi[nowusing]->haoma == 0)
{
s.lifevalue -= sword;
nowusing++;
if (nowusing == wuqitotal + 1)
nowusing = 0;
}
else if (wuqi[nowusing]->haoma == 1)
{
s.lifevalue -= bomb;
if (variety != 1) {
lifevalue -= bombfantan;
}
wuqi[nowusing] = nullptr;//bomb用过一次就没了
nowusing++;
if (nowusing == wuqitotal + 1)
nowusing = 0;
}
else if (wuqi[nowusing]->haoma == 2)
{
s.lifevalue -= arrow;
wuqi[nowusing]->usingTime++;
if (wuqi[nowusing]->usingTime == 2)
wuqi[nowusing] = nullptr;//用过两次就没了
nowusing++;
if (nowusing == wuqitotal + 1)
nowusing = 0;
}
}
}
};//攻击对方。并且按照我的逻辑,攻击一次要判断是否有武士死亡
virtual void win(Warriors* t, int loc)
{
int rob = 0;//记录共抢走了多少个
if (t->wuqitotal >= 0) {
for (int i = 0; i <= t->wuqitotal; i++)
{
if (t->wuqi[i] == nullptr)
i++;
if (wuqitotal >= 9 || i > t->wuqitotal)
break;
if ((t->wuqi[i])->haoma == 2&& (t->wuqi[i])->usingTime >= 1)
{
continue;
}
else
{
wuqitotal++;
rob++;
wuqi[wuqitotal] = t->wuqi[i];
wuqinum[(t->wuqi[i])->haoma]++;
t->wuqinum[(t->wuqi[i])->haoma]--;
t->wuqi[i] = nullptr;
}
}
if (wuqitotal < 9)
{
for (int i = 0; i <= t->wuqitotal; i++)
{
if (wuqitotal >= 9)
break;
if (t->wuqi[i] != nullptr) {
if ((t->wuqi[i])->haoma == 2)
{
rob++;
wuqitotal++;
wuqi[wuqitotal] = t->wuqi[i];
wuqinum[(t->wuqi[i])->haoma]++;
t->wuqinum[(t->wuqi[i])->haoma]--;
t->wuqi[i] = nullptr;
}
}
}
}
t->wuqitotal -= rob;
}
putTime(Time);
cout << siling.colorname << " " << warriorname[variety] << " " << bianhao << " killed " << t->siling.colorname << " " << t->warriorname[t->variety] << " " << t->bianhao << " in city " << loc << " remaining " << lifevalue << " elements" << endl;
t->location = N + 3;//死了,相当于远离这个战场
}//进行获胜之后的操作,胜利者的操作
virtual void Yell() {};
};
void sortbefore(Warriors* war);
class Dragon :public Warriors {
public:
virtual void making(int n, Head& m)
{
variety = 0;
attack = gongji[0];//攻击力
lifevalue = value[0];//生命值初始
siling = m;//所属司令
bianhao = n;//编号
location = siling.zone;//初始位置在司令部
wuqi[0] = new Weapon(bianhao % 3);//拥有武器
wuqinum[bianhao % 3]++;
wuqitotal++;
nowusing = 0;//正在用0号武器
m.initiallife -= lifevalue;//制造时司令部要减少生命元
siling.initiallife -= lifevalue;//制造时司令部要减少生命元
putTime(Time);
cout << siling.colorname << " dragon " << bianhao << " born" << endl;
}
Dragon(int n, int V, Head& t)
{
variety = V;
making(n, t);
}//编号,数字代表的武器种类,所属的司令部
virtual void goahead()
{
if (lifevalue > 0) {
if (siling.color == 0)
location++;
else
location--;
}
}
virtual void Yell()
{
if (lifevalue > 0)
{
putTime(Time);
cout << siling.colorname << " dragon " << bianhao << " yelled in city " << location << endl;
}
}
};
class Ninja :public Warriors {
public:
virtual void making(int n, Head& m)
{
variety = 1;
lifevalue = value[1];
attack = gongji[1];
siling = m;
bianhao = n;
location = siling.zone;
wuqi[0] = new Weapon(bianhao % 3);
wuqi[1] = new Weapon((bianhao + 1) % 3);
wuqinum[bianhao % 3]++;
wuqinum[(bianhao + 1) % 3]++;
wuqitotal += 2;
nowusing = 0;
m.initiallife -= lifevalue;//制造时司令部要减少生命元
siling.initiallife -= lifevalue;
putTime(Time);
cout << siling.colorname << " ninja " << bianhao << " born" << endl;
}
Ninja(int n, int V, Head& t)
{
variety = V;
making(n, t);
}//编号,数字代表的武器种类,所属的司令部
virtual void goahead()
{
if (lifevalue > 0) {
if (siling.color == 1)
location--;
else
location++;
}
}
};
class Iceman :public Warriors {
public:
virtual void making(int n, Head& m)
{
variety = 2;
lifevalue = value[2];
attack = gongji[2];
bianhao = n;
siling = m;
location = siling.zone;
wuqi[0] = new Weapon(bianhao % 3);
wuqinum[bianhao % 3]++;
wuqitotal++;
nowusing = 0;
m.initiallife -= lifevalue;//制造时司令部要减少生命元
siling.initiallife -= lifevalue;
putTime(Time);
cout << siling.colorname << " iceman " << bianhao << " born" << endl;
}
Iceman(int n, int V, Head& t)
{
variety = V;
making(n, t);
}//编号,数字代表的武器种类,所属的司令部
virtual void goahead()
{
if (lifevalue > 0) {
if (siling.color == 1)
location--;
else
location++;
int decline = lifevalue / 10;
lifevalue -= decline;//生命元要减少
}
}
};
class Lion :public Warriors {
public:
int loyalty;
virtual void making(int n, Head& m)
{
variety = 3;
siling = m;
lifevalue = value[3];
attack = gongji[3];
bianhao = n;
location = siling.zone;
wuqi[0] = new Weapon(bianhao % 3);
wuqinum[bianhao % 3]++;
wuqitotal++;
nowusing = 0;
m.initiallife -= lifevalue;//制造时司令部要减少生命元
siling.initiallife -= lifevalue;
loyalty = m.initiallife;
putTime(Time);
cout << siling.colorname << " lion " << bianhao << " born" << endl;
cout << "Its loyalty is " << loyalty << endl;
}
Lion(int n, int V, Head& t)
{
variety = V;
making(n, t);
}//编号,数字代表的武器种类,所属的司令部
virtual void goahead()
{
if (lifevalue > 0) {
if (siling.color == 1)
location--;
else
location++;
loyalty -= K;
}
}
virtual void runaway()
{
if (loyalty <= 0 && location != N + 1 - siling.zone && location <= N + 1)
{
lifevalue = 0;
location = N + 3;
putTime(Time);
cout << siling.colorname << " lion " << bianhao << " ran away" << endl;
}
}
};
class Wolf :public Warriors {
public:
virtual void making(int n, Head& m)
{
variety = 4;
siling = m;
lifevalue = value[4];
attack = gongji[4];
bianhao = n;
location = siling.zone;
nowusing = 0;
m.initiallife -= lifevalue;//制造时司令部要减少生命元
siling.initiallife -= lifevalue;
putTime(Time);
cout << siling.colorname << " wolf " << bianhao << " born" << endl;
}
Wolf(int n, int V, Head& t)
{
variety = V;
making(n, t);
}//编号,数字代表的武器种类,所属的司令部
virtual void goahead()
{
if (lifevalue > 0) {
if (siling.color == 1)
location--;
else
location++;
}
}
void bisaizhunbei(Warriors* t, int loc)
{
if (t->variety != 4) {
sortbefore(t);
if (t->wuqitotal >= 0) {
int qiang = t->wuqi[0]->haoma;//要抢的类
int zongshu = 0;//抢走总数
for (int i = 0; i <= t->wuqitotal; i++)
{
if (wuqitotal >= 9)
break;
if ((t->wuqi[i])->haoma == qiang) {
if (qiang == 2&& (t->wuqi[i])->usingTime >= 1)
{
continue;
}
else
{
wuqitotal++;
wuqi[wuqitotal] = t->wuqi[i];
wuqinum[qiang]++;
t->wuqinum[qiang]--;
t->wuqi[i] = nullptr;
zongshu++;
}
}
}//以下为如果还小于10,就取那些用过2次的
if (wuqitotal < 9)
{
if (qiang == 2) {
for (int i = 0; i <= t->wuqitotal; i++)
{
if (t->wuqi[i] != nullptr) {
if (wuqitotal >= 9)
break;
if ((t->wuqi[i])->haoma == 2)
{
if ((t->wuqi[i])->usingTime >= 1)
{
wuqitotal++;
wuqi[wuqitotal] = t->wuqi[i];
wuqinum[2]++;
t->wuqinum[2]--;
t->wuqi[i] = nullptr;
zongshu++;
}
}
}
}
}
}
putTime(Time);
cout << siling.colorname << " wolf " << bianhao << " took " << zongshu << " " << (wuqi[wuqitotal])->wuqiname[qiang] << " from " << t->siling.colorname << " " << t->warriorname[t->variety] << " " << t->bianhao<< " in city " << loc << endl;
}
}
}
};
void sortbefore(Warriors* war)
{
Warriors fuzhipin = *war;
war->wuqitotal = -1;
for (int i = 0; i <= fuzhipin.wuqitotal; i++)
{
if (fuzhipin.wuqi[i] != nullptr)
war->wuqi[++war->wuqitotal] = fuzhipin.wuqi[i];
}
for (int i = 0; i < war->wuqitotal; i++)
{
for (int j = i; j <= war->wuqitotal; j++) {
if (war->wuqi[i]->haoma > war->wuqi[j]->haoma)
{
Weapon* tmp = war->wuqi[i];
war->wuqi[i] = war->wuqi[j];
war->wuqi[j] = tmp;
}//要按编号从小到大排
if (war->wuqi[i]->haoma == war->wuqi[j]->haoma)
{
if (war->wuqi[i]->usingTime > war->wuqi[j]->usingTime)
{
Weapon* tmp = war->wuqi[i];
war->wuqi[i] = war->wuqi[j];
war->wuqi[j] = tmp;
}//用过的放在后面
}
}
}
war->nowusing = 0;
}
bool tie(Warriors* a, Warriors* b)
{
if (a->isdie() && b->isdie())
return true;
if (a->wuqitotal <= -1 && b->wuqitotal <= -1)
return true;
return false;
}//判断是否平局
void Compete(Warriors* a, Warriors* b, int loc)
{
//a是红方,b是蓝方
sortbefore(a);
sortbefore(b);
int max = 200;
if (loc % 2 != 0)
{
bool finish = false;
while (!finish&&max>=0)
{
max--;
a->offence(*b);
if (tie(a, b))
{
putTime(Time);
if (a->isdie() && b->isdie())
{
cout << "both red " << a->warriorname[a->variety] << " " << a->bianhao << " and blue " << b->warriorname[b->variety] << " " << b->bianhao << " died in city " << loc << endl;
a->location = N + 3;
b->location = N + 3;
a->Yell();
b->Yell();
}
else
{
cout << "both red " << a->warriorname[a->variety] << " " << a->bianhao << " and blue " << b->warriorname[b->variety] << " " << b->bianhao << " were alive in city " << loc << endl;
a->Yell();
b->Yell();
}
finish = true;
}//平局的展示
else if (a->isdie())
{
b->win(a, loc);
b->Yell();
finish = true;
}//a死了
else if (b->isdie())
{
a->win(b, loc);
a->Yell();
finish = true;
}//b死了
else//如果没有平局,ab都还活着,那么就轮到b进行攻击
{
b->offence(*a);
if (tie(a, b))
{
putTime(Time);
if (a->isdie() && b->isdie())
{
cout << "both red " << a->warriorname[a->variety] << " " << a->bianhao << " and blue " << b->warriorname[b->variety] << " " << b->bianhao << " died in city " << loc << endl;
a->location = N + 3;
b->location = N + 3;
a->Yell();
b->Yell();
}
else
{
cout << "both red " << a->warriorname[a->variety] << " " << a->bianhao << " and blue " << b->warriorname[b->variety] << " " << b->bianhao << " were alive in city " << loc << endl;
a->Yell();
b->Yell();
}
finish = true;
}//平局的展示
else if (a->isdie())
{
b->win(a, loc);
a->Yell();
b->Yell();
finish = true;
}//a死了
else if (b->isdie())
{
a->win(b, loc);
a->Yell();
b->Yell();
finish = true;
}
}
}
}
else
{
bool finish = false;
while (!finish&&max>=0)
{
max--;
b->offence(*a);
if (tie(a, b))
{
putTime(Time);
if (a->isdie() && b->isdie())
{
cout << "both red " << a->warriorname[a->variety] << " " << a->bianhao << " and blue " << b->warriorname[b->variety] << " " << b->bianhao << " died in city " << loc << endl;
a->location = N + 3;
b->location = N + 3;
a->Yell();
b->Yell();
}
else
{
cout << "both red " << a->warriorname[a->variety] << " " << a->bianhao << " and blue " << b->warriorname[b->variety] << " " << b->bianhao << " were alive in city " << loc << endl;
a->Yell();
b->Yell();
}
finish = true;
}//平局的展示
else if (a->isdie())
{
b->win(a, loc);
a->Yell();
b->Yell();
finish = true;
}//a死了
else if (b->isdie())
{
a->win(b, loc);
a->Yell();
b->Yell();
finish = true;
}
else
{
a->offence(*b);
if (tie(a, b))
{
putTime(Time);
if (a->isdie() && b->isdie())
{
cout << "both red " << a->warriorname[a->variety] << " " << a->bianhao << " and blue " << b->warriorname[b->variety] << " " << b->bianhao << " died in city " << loc << endl;
a->location = N + 3;
b->location = N + 3;
a->Yell();
b->Yell();
}
else
{
cout << "both red " << a->warriorname[a->variety] << " " << a->bianhao << " and blue " << b->warriorname[b->variety] << " " << b->bianhao << " were alive in city " << loc << endl;
a->Yell();
b->Yell();
}
finish = true;
}//平局的展示
else if (a->isdie())
{
b->win(a, loc);
a->Yell();
b->Yell();
finish = true;
}//a死了
else if (b->isdie())
{
a->win(b, loc);
a->Yell();
b->Yell();
finish = true;
}
}
max--;
}
}
if (!a->isdie() && !b->isdie() && !tie(a, b)) {
putTime(Time);
cout << "both red " << a->warriorname[a->variety] << " " << a->bianhao << " and blue " << b->warriorname[b->variety] << " " << b->bianhao << " were alive in city " << loc << endl;
a->Yell();
b->Yell();
}
}
int main()
{
int t;
cin >> t;
int redlist[5] = { 2,3,4,1,0 };
int bluelist[5] = { 3,0,1,2,4 };
for (int Case = 1; Case <= t; Case++)
{
int reduse = 0, blueuse = 0;//正在使用的武士为第几个,作为数组下标用
int rednum = 0, bluenum = 0;//总数
bool conclude = false;//判断是否结束
bool reddie = false, bluedie = true;
bool redstopmaking = false, bluestopmaking = false;
int M, T;
cin >> M >> N >> K >> T;
for (int i = 0; i < 5; i++)
cin >> value[i];
for (int i = 0; i < 5; i++)
cin >> gongji[i];
cout << "Case " << Case << ":" << endl;
Head redl(0, M), bluel(1, M);
Warriors* redbing[100] = { nullptr };
Warriors* bluebing[100] = { nullptr };
for (Time = 0; Time <= T; Time += 5)
{
if (Time % 60 == 0)
{
if (!redstopmaking)
{
if (value[redlist[reduse]] > redl.initiallife) {
redstopmaking = true;
}
else {
rednum++;
if (redlist[reduse] == 0)
redbing[Time / 60] = new Dragon(Time / 60 + 1, redlist[reduse], redl);
else if (redlist[reduse] == 1)
redbing[Time / 60] = new Ninja(Time / 60 + 1, redlist[reduse], redl);
else if (redlist[reduse] == 2)
redbing[Time / 60] = new Iceman(Time / 60 + 1, redlist[reduse], redl);
else if (redlist[reduse] == 3)
redbing[Time / 60] = new Lion(Time / 60 + 1, redlist[reduse], redl);
else if (redlist[reduse] == 4)
redbing[Time / 60] = new Wolf(Time / 60 + 1, redlist[reduse], redl);
reduse++;
if (reduse >= 5)
reduse = 0;
}
}
if (!bluestopmaking)
{
if (value[bluelist[blueuse]] > bluel.initiallife)
{
bluestopmaking = true;
}
else
{
bluenum++;
if (bluelist[blueuse] == 0)
bluebing[Time / 60] = new Dragon(Time / 60 + 1, bluelist[blueuse], bluel);
else if (bluelist[blueuse] == 1)
bluebing[Time / 60] = new Ninja(Time / 60 + 1, bluelist[blueuse], bluel);
else if (bluelist[blueuse] == 2)
bluebing[Time / 60] = new Iceman(Time / 60 + 1, bluelist[blueuse], bluel);
else if (bluelist[blueuse] == 3)
bluebing[Time / 60] = new Lion(Time / 60 + 1, bluelist[blueuse], bluel);
else if (bluelist[blueuse] == 4)
bluebing[Time / 60] = new Wolf(Time / 60 + 1, bluelist[blueuse], bluel);
blueuse++;
if (blueuse >= 5)
blueuse = 0;
}
}
}
else if (Time % 60 == 5)
{
for (int j = 1; j <= N; j++)
{
for (int i = 0; i < rednum; i++)
{
if (redbing[i]->location == j)
redbing[i]->runaway();
}
for (int i = 0; i < bluenum; i++)
{
if (bluebing[i]->location == j)
bluebing[i]->runaway();
}
}
}
else if (Time % 60 == 10)
{
for (int i = 0; i < rednum; i++)
{
redbing[i]->goahead();
if (redbing[i]->isconquer()) {
bluedie = true;
conclude = true;
}
}
for (int i = 0; i < bluenum; i++) {
bluebing[i]->goahead();
if (bluebing[i]->isconquer()) {
reddie = true;
conclude = true;
}
}
for (int j = 0; j <= N + 1; j++)
{
for (int i = 0; i < rednum; i++)
{
if (redbing[i]->location == j)
redbing[i]->aftergo();
}
for (int i = 0; i < bluenum; i++)
{
if (bluebing[i]->location == j)
bluebing[i]->aftergo();
}
}
if (conclude)
{
break;
}
}
else if (Time % 60 == 35)
{
for (int j = 1; j <= N; j++) {
for (int i = 0; i < rednum; i++)
{
if (redbing[i]->variety == 4 && redbing[i]->location == j)
{
for (int j = 0; j < bluenum; j++)
{
if (bluebing[j]->location == redbing[i]->location)
redbing[i]->bisaizhunbei(bluebing[j], redbing[i]->location);
}
}
}
for (int i = 0; i < bluenum; i++)
{
if (bluebing[i]->variety == 4 && bluebing[i]->location == j)
{
for (int j = 0; j < rednum; j++)
{
if (redbing[j]->location == bluebing[i]->location)
bluebing[i]->bisaizhunbei(redbing[j], bluebing[i]->location);
}
}
}
}
}
else if (Time % 60 == 40)
{
for (int s = 1; s <= N; s++) {
for (int i = 0; i < rednum; i++) {
for (int j = 0; j < bluenum; j++)
{
if (redbing[i]->location == s && bluebing[j]->location == s) {
Compete(redbing[i], bluebing[j], s);
break;
}
}
}
}
}
else if (Time % 60 == 50)
{
redl.talk();
bluel.talk();
}
else if (Time % 60 == 55)
{
for (int j = 1; j <= N; j++)
{
for (int i = 0; i < rednum; i++) {
if (redbing[i]->location == j)
redbing[i]->show();
}
for (int i = 0; i < bluenum; i++) {
if (bluebing[i]->location == j)
bluebing[i]->show();
}
}
}
}
}
return 0;
}