|
题目链接 OpenJudge - E:魔兽世界三(开战)
听说上课大家讲了面向对象编程,我思考了一下,想试试单纯靠之前知识不用class封装行不行,决定面向过程(其实就是胡乱写)写一下这题
思路就是首先按照题目给出的时间顺序,写9个namespace封装9个需要输出的过程。然后每个namespace在去具体实现,思考的时候会发现可以合并部分相同时间的事情(好像也不得不合并,比如抵达司令部)
具体实现的过程,我们只实现两个司令部的class,对于每个武士,其被所在司令部+司令部内编号唯一确定,因而我用两个int(id,color)来实现武士信息的传递,调用武士信息只需要调用司令部内数组
对于每个城市的位置用一个set记录该位置上有哪些人,用vector<pair<int,int> >来存放武器信息。这样的好处是不需要写一个数据结构支持单点删除,和自动排序(每个城市让红武士在前,以及抢夺武器时的排序,虽然看上去实现的好不需要自动排序)
一些题目中没有的细节:
- 如果武士面对面走到另一方的城市,他们不会发生战斗
- 如果武士抵达了司令部,则不需要输出其「移动」的信息,也就是说3,7不同时输出
可能会写错的地方:
- 如何判断战斗状态已经终止,我建议大力跑200次循环,因为每个武士血量小于200,而且总数量小于1e5,不会TLE
- 抢夺武器时的排序,我的实现为了方便(不重载运算符)会改变武器的使用信息,记得在战斗开始前重新检视每一把武器,遵循用的时候再检查的原则。
- 清空的时候别忘了清空当前累计时间。。
不错的输出方法:
用sprintf,与string的data()函数,能容易的把int和string一起放到字符串里。具体可以看代码中的实现。
/*
面向过程编程
他说什么你写什么。
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
#define pii pair<int, int>
#define se second
#define fi first
#define mkp(x, y) (make_pair(x, y))
#define db double
#define ins insert
using namespace std;
const int MAXN = 1.5e5; // 1.5倍
const int MAXT = 22;
const int inf = 1e9;
int M, N, K, T;
int ntime;
bool isRunning = 1;
int foc[MAXT];
int wsb[MAXT];
set<int> np[MAXT];
string scol[] = {&#34;red&#34;, &#34;blue&#34;};
string wnm[] = {&#34;dragon&#34;, &#34;ninja&#34;, &#34;iceman&#34;, &#34;lion&#34;, &#34;wolf&#34;};
string wpnm[] = {&#34;sword&#34;, &#34;bomb&#34;, &#34;arrow&#34;};
pair<int, int> wp[] = {mkp(0, inf), mkp(1, 1), mkp(2, 2)};
class slb
{
public:
int bld; // 司令部血量
int ord[MAXT]; // 输出武士的顺序
int cnt; // 总共有多少武士
vector<pair<int, int>> wp[MAXN]; // 武士武器
int wct[MAXN]; // 第i个武士是什么
int nwp[MAXN]; // 武士现在用到哪把武器了
int rsb[MAXN]; // 武士剩余血量
int loy[MAXN]; // 武士忠诚度
void clean()
{
for (int i = 0; i <= cnt; ++i)wp.clear();
bld = cnt = 0;
memset(wct, 0, sizeof(wct));
memset(ord, 0, sizeof(ord));
memset(loy, 0, sizeof(loy));
memset(rsb, 0, sizeof(rsb));
memset(nwp, 0, sizeof(nwp));
}
} tm[2];
inline void init()
{
tm[1].bld = M;
tm[0].bld = M;
tm[0].ord[0] = 2;
tm[0].ord[1] = 3;
tm[0].ord[2] = 4;
tm[0].ord[3] = 1;
tm[0].ord[4] = 0;
tm[1].ord[0] = 3;
tm[1].ord[1] = 0;
tm[1].ord[2] = 1;
tm[1].ord[3] = 2;
tm[1].ord[4] = 4;
return;
}
void fightInit(int id, int cl)
{
tm[cl].nwp[id] = 0;
for(int i=0;i<tm[cl].wp[id].size();++i){
if(tm[cl].wp[id].se < 0){
tm[cl].wp[id].se *= -1;
}
}
sort(tm[cl].wp[id].begin(), tm[cl].wp[id].end());
}
void robinit(int i1,int cl){
slb &a = tm[cl];
for(int i=0;i<a.wp[i1].size();++i)
if(a.wp[i1].first == 2)
a.wp[i1].second *= -1;
sort(a.wp[i1].begin(),a.wp[i1].end());
}
namespace _1
{
int nbrn[2];
int u = 0,v = 0;
int realborn(int cl)
{
slb &a = tm[cl];
int p = a.ord[nbrn[cl]];
if (wsb[p] > a.bld)
return -1;
int &id = a.cnt;
id++;
printf((&#34;%03d:00 &#34; + scol[cl] +&#34; &#34; + wnm[p] + &#34; %d born\n&#34;).data(), ntime, id);
if (cl == 1){
np[N + 1].ins(id);
}
if (cl == 0){
np[0].ins(-id);
}
a.bld -= wsb[p];
if (p == 3){
a.loy[id] = a.bld;
printf(&#34;Its loyalty is %d\n&#34;,a.bld);
}
else
a.loy[id] = 1;
if (p != 4)
{
a.wp[id].push_back(wp[id % 3]);
if (p == 1)
a.wp[id].push_back(wp[(id + 1) % 3]);
}
a.rsb[id] = wsb[p];
a.wct[id] = p;
nbrn[cl] ++;
nbrn[cl] %= 5;
return 0;
}
void Born()
{
if(u!=-1)u = realborn(0);
if(v!=-1)v = realborn(1);
}
};
namespace _2
{
void runn(int id, int cl)
{
printf((&#34;%03d:05 &#34; + scol[cl] + &#34; lion %d ran away\n&#34;).data(), ntime, id);
}
void Run()
{
int tmp[MAXT], tp = 0;
for (int i = 0; i <= N + 1; ++i)
{
tp = 0;
for (auto k : np)
{
int cl = k > 0 ? 1 : 0;
int p = abs(k);
if (tm[cl].loy[p] <= 0)
{
runn(p, cl);
tmp[++tp] = k;
}
else if (tm[cl].wct[p] == 3)
{
tm[cl].loy[p] -= K;
}
}
for (int j = 1; j <= tp; ++j)
{
np.erase(tmp[j]);
}
}
}
};
namespace _3
{
void outmove(int id, int wher, int cl)
{
printf((&#34;%03d:10 &#34; + scol[cl] + &#34; &#34; + wnm[tm[cl].wct[id]] +
&#34; %d marched to city %d with %d elements and force %d\n&#34;)
.data(),
ntime, id, wher, tm[cl].rsb[id], foc[tm[cl].wct[id]]);
}
void achieve(int id, int cl)
{
isRunning = 0;
printf((&#34;%03d:10 &#34; + scol[cl] + &#34; &#34; + wnm[tm[cl].wct[id]] + &#34; %d reached &#34; + scol[cl^1] +
&#34; headquarter with %d elements and force %d\n&#34;)
.data(), ntime, id, tm[cl].rsb[id], foc[tm[cl].wct[id]]);
printf((&#34;%03d:10 &#34; + scol[cl^1] + &#34; headquarter was taken\n&#34;).data(), ntime);
}
void Move()
{
slb &a = tm[0];
slb &b = tm[1];
for (auto k : np[1])
{
if (k > 0)
{
if(b.wct[k] == 2)b.rsb[k] = b.rsb[k] - b.rsb[k] / 10;
achieve(k, 1);
}
}
for (int i = 1; i <= N; ++i)
{
for (auto k : np[i - 1])
{
if (k < 0)
{
if(a.wct[-k] == 2)a.rsb[-k] = a.rsb[-k] - a.rsb[-k] / 10;
outmove(-k, i, 0);
}
}
for (auto k : np[i + 1])
{
if (k > 0)
{
if(b.wct[k] == 2)b.rsb[k] = b.rsb[k] - b.rsb[k] / 10;
outmove(k, i, 1);
}
}
}
for (auto k : np[N])
{
if (k < 0)
{
if(a.wct[-k] == 2)a.rsb[-k] = a.rsb[-k] - a.rsb[-k] / 10;
achieve(-k, 0);
}
}
for(int i=2;i<=N+1;++i){
for(auto k : np){
if(k > 0){
np[i - 1].ins(k);
np.erase(k);
break;
}
}
}
for(int i=N-1;i>=0;--i){
for(auto k : np){
if(k < 0){
np[i+1].ins(k);
np.erase(k);
break;
}
}
}
return ;
}
};
namespace _4
{
void rbreport(int i1,int i2,int num,int kd,int wher,int cl){
int p1 = tm[cl].wct[i1];
int p2 = tm[cl^1].wct[i2];
printf((&#34;%03d:35 &#34;+scol[cl]+&#34; &#34;+wnm[p1] + &#34; %d took %d &#34; + wpnm[kd] +
&#34; from &#34;+scol[cl^1] + &#34; &#34; + wnm[p2] +&#34; %d in city %d\n&#34;).data(),ntime,i1,num,i2,wher);
}
void solverb(int i1,int i2,int wher,int cl){
slb &a = tm[cl];
slb &b = tm[cl^1];
if(a.wct[i1] == 4 && b.wp[i2].size()>0){
robinit(i2,cl^1);
int i = 0;
for(;i<b.wp[i2].size();++i){
if(i!=0 && b.wp[i2].first>b.wp[i2][i-1].first)break;
a.wp[i1].push_back(b.wp[i2]);
}
rbreport(i1,i2,i,b.wp[i2][0].fi,wher,cl);
b.wp[i2].erase(b.wp[i2].begin(),b.wp[i2].begin()+i);
}
}
void Snatch(){
int tmp[MAXT],tp = 0;
for(int i=1;i<=N;++i){
tp = 0;
for(auto k : np)tmp[++tp] = k;
if(tp < 2)continue;
tmp[1] = -tmp[1];
if(tm[0].wct[tmp[1]] == tm[1].wct[tmp[2]])continue;
int cl=0;
int i1 = tmp[1],i2 = tmp[2];
if(tm[1].wct[i2] == 4){
swap(i1,i2);
cl = 1;
}
solverb(i1,i2,i,cl);
}
}
};
namespace _5
{
#define ra (tm[cl])
int fight(int id, int cl)
{
if (ra.nwp[id] >= ra.wp[id].size())
ra.nwp[id] = 0;
for (int &i = ra.nwp[id]; i < (int)ra.wp[id].size(); ++i)
{
if (ra.wp[id].se > 0)
{
if(ra.wp[id].fi!=0)ra.wp[id].se--;
int p = ra.wp[id].fi;
if(ra.wp[id].se == 0) ra.wp[id].erase(ra.wp[id].begin() + i);
else ++i;
return p;
}
}
return -1;
}
void hurt(int i1, int c1, int i2, int c2, int kd)
{
if (kd == -1)
return;
slb &a = tm[c1];
slb &b = tm[c2];
int nf = foc[b.wct[i2]];
if (kd == 0)
{
nf = nf * 2 / 10;
a.rsb[i1] -= nf;
}
else if (kd == 1)
{
nf = nf * 4 / 10;
a.rsb[i1] -= nf;
if (b.wct[i2] != 1)
{
nf /= 2;
b.rsb[i2] -= nf;
}
}
else if (kd == 2)
{
nf = nf * 3 / 10;
a.rsb[i1] -= nf;
}
}
bool dead(int id, int cl)
{
if (ra.rsb[id] <= 0){
return 1;
}
return 0;
}
int __o1 = -1;
bool notchange(int i1, int c1, int i2, int c2)
{
++__o1;
if(__o1==200)return 1;
return 0;
}
inline void outPK(int i1, int i2, int wher)
{
string s;
s.clear();
char t[100];
memset(t,0,sizeof(t));
slb &a = tm[0];
slb &b = tm[1];
/* 这里写麻烦了,我应该用col数组的。。。。*/
if (dead(i1, 0) && not dead(i2, 1))
{
np[wher].erase(-i1);
sprintf(t, (&#34;%03d:40 blue &#34; + wnm[b.wct[i2]] + &#34; %d killed red &#34; + wnm[a.wct[i1]] + &#34; %d in city %d remaining %d elements&#34;).data(),
ntime, i2, i1, wher, b.rsb[i2]);
if (b.wct[i2] == 0)
{
s = s + t + &#34;\n&#34;;
sprintf(t, (&#34;%03d:40 blue dragon %d yelled in city %d&#34;), ntime, i2, wher);
}
}
else if (dead(i2, 1) && not dead(i1, 0))
{
np[wher].erase(i2);
sprintf(t, (&#34;%03d:40 red &#34; + wnm[a.wct[i1]] + &#34; %d killed blue &#34; + wnm[b.wct[i2]] + &#34; %d in city %d remaining %d elements&#34;).data(),
ntime, i1, i2, wher, a.rsb[i1]);
if (a.wct[i1] == 0)
{
s = s + t + &#34;\n&#34;;
sprintf(t, (&#34;%03d:40 red dragon %d yelled in city %d&#34;), ntime, i1, wher);
}
}
else if (dead(i1, 0) && dead(i2, 1))
{
np[wher].erase(-i1);
np[wher].erase(i2);
sprintf(t, (&#34;%03d:40 both red &#34; + wnm[a.wct[i1]] + &#34; %d and blue &#34; + wnm[b.wct[i2]] + &#34; %d died in city %d&#34;).data(),
ntime, i1, i2, wher);
}
else if (not dead(i1, 0) && not dead(i2, 1))
{
sprintf(t, (&#34;%03d:40 both red &#34; + wnm[a.wct[i1]] + &#34; %d and blue &#34; + wnm[b.wct[i2]] + &#34; %d were alive in city %d&#34;).data(),
ntime, i1, i2, wher);
if (a.wct[i1] == 0)
{
s = s + t + &#34;\n&#34;;
sprintf(t, (&#34;%03d:40 red dragon %d yelled in city %d&#34;), ntime, i1, wher);
}
if (b.wct[i2] == 0)
{
s = s + t + &#34;\n&#34;;
sprintf(t, (&#34;%03d:40 blue dragon %d yelled in city %d&#34;), ntime, i2, wher);
}
}
s += t;
cout<<s<<&#34;\n&#34;;
return;
}
void rob(int i1,int i2){
if((dead(i1,0) && dead(i2,1)) || (!dead(i1,0) && !dead(i2,1)))return ;
int cl = 0;
if(dead(i2,1)){
cl ^=1;
swap(i1,i2);
}
slb &a = tm[cl];
slb &b = tm[cl^1];
robinit(i1,cl);
for(auto u : a.wp[i1]){
if(b.wp[i2].size()>=10)break;
b.wp[i2].push_back(u);
}
return ;
}
void PK(int ri, int bi, int wft, int wher)
{
fightInit(ri, 0);
fightInit(bi, 1);
if (wft == 1)
hurt(ri, 0, bi, 1, fight(bi, 1));
while (!((dead(ri, 0)) || (dead(bi, 1)) || notchange(ri, 0, bi, 1)))
{
hurt(bi, 1, ri, 0, fight(ri, 0));
if (((dead(ri, 0)) || (dead(bi, 1))))
break;
hurt(ri, 0, bi, 1, fight(bi, 1));
}
rob(ri,bi);
outPK(ri, bi, wher);
__o1 = -1;
return;
}
void StartFight()
{
int tmp[MAXT],tp = 0;
for(int i=1;i<=N;++i){
if(np.size()<2)continue;
else {
tp = 0;
for(auto k : np)tmp[++tp] = k;
tmp[1] *= -1;
int wft;
if(i&1){
wft = 0;
}else {
wft = 1;
}
PK(tmp[1],tmp[2],wft,i);
}
}
}
};
namespace _6
{
void Cheer();
};
namespace _7
{
void Arrived_Occupied();
};
namespace _8
{
void slbReport(){
printf(&#34;%03d:50 %d elements in red headquarter\n&#34;,ntime,tm[0].bld);
printf(&#34;%03d:50 %d elements in blue headquarter\n&#34;,ntime,tm[1].bld);
}
};
namespace _9
{
void wsReport(){
for(int i=0;i<=N+1;++i){
for(auto k : np){
int tmp[5];
tmp[0]=tmp[1]=tmp[2]=0;
int cl;
if(k > 0)cl = 1;
else cl = 0;
if(k < 0) k = -k;
slb &a = tm[cl];
for(int i=0;i<a.wp[k].size();++i){
tmp[a.wp[k].first]++;
}
printf((&#34;%03d:55 &#34;+scol[cl]+&#34; &#34;+wnm[a.wct[k]]+&#34; %d has %d sword %d bomb %d arrow and %d elements\n&#34;).data(),ntime,k,tmp[0],tmp[1],tmp[2],a.rsb[k]);
}
}
}
};
void clear()
{
tm[0].clean();
tm[1].clean();
for(int i=0;i<=N+1;++i)np.clear();
memset(foc,0,sizeof(foc));
memset(wsb,0,sizeof(wsb));
ntime = 0;
isRunning = 1;
_1::u = 0;
_1::v = 0;
_1::nbrn[0]=_1::nbrn[1] = 0;
}
int main()
{
int __T;
scanf(&#34;%d&#34;, &__T);
for (int __i = 1; __i <= __T; ++__i)
{
scanf(&#34;%d%d%d%d&#34;, &M, &N, &K, &T);
for (int i = 0; i < 5; ++i)
scanf(&#34;%d&#34;, &wsb);
for (int i = 0; i < 5; ++i)
scanf(&#34;%d&#34;, &foc);
init();
printf(&#34;Case %d:\n&#34;,__i);
int ttim = 0;
for (; ntime * 60 + ttim <= T; ++ntime)
{
ttim = 0;
_1::Born();
ttim = 5;
if(ntime * 60 + ttim <= T)
_2::Run();
ttim = 10;
if(ntime * 60 + ttim <= T)
_3::Move();
if(!isRunning)break;
ttim = 35;
if(ntime * 60 + ttim <= T)
_4::Snatch();
ttim = 40;
if(ntime * 60 + ttim <= T)
_5::StartFight();
ttim = 50;
if(ntime * 60 + ttim <= T){
_8::slbReport();
}
ttim = 55;
if(ntime * 60 + ttim <= T){
_9::wsReport();
}
ttim = 0;
}
clear();
}
return 0;
}
/*
放一点编译选项和文件比较命令
diff -u --ignore-space-change --strip-trailing-cr --ignore-blank-lines test.out datapub.out
g++ 6E.cpp -std=c++20 -O2 -Wno-deprecated-declarations
*/ |
|