搜索
热搜: 活动 交友 discuz
查看: 107|回复: 0

程序设计实习 魔兽世界三(开战)

[复制链接]

2

主题

6

帖子

10

积分

新手上路

Rank: 1

积分
10
发表于 2023-4-6 04:22:31 | 显示全部楼层 |阅读模式
题目链接 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[] = {"red", "blue"};
string wnm[] = {"dragon", "ninja", "iceman", "lion", "wolf"};
string wpnm[] = {"sword", "bomb", "arrow"};
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(("%03d:00 " + scol[cl] +" " + wnm[p] + " %d born\n").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("Its loyalty is %d\n",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(("%03d:05 " + scol[cl] + " lion %d ran away\n").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(("%03d:10 " + scol[cl] + " " + wnm[tm[cl].wct[id]] +
                " %d marched to city %d with %d elements and force %d\n")
                   .data(),
               ntime, id, wher, tm[cl].rsb[id], foc[tm[cl].wct[id]]);
    }
    void achieve(int id, int cl)
    {
        isRunning = 0;
        printf(("%03d:10 " + scol[cl] + " " + wnm[tm[cl].wct[id]] + " %d reached " + scol[cl^1] +
        " headquarter with %d elements and force %d\n")
        .data(), ntime, id, tm[cl].rsb[id], foc[tm[cl].wct[id]]);
        printf(("%03d:10 " + scol[cl^1] + " headquarter was taken\n").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(("%03d:35 "+scol[cl]+" "+wnm[p1] + " %d took %d " + wpnm[kd] +
        " from "+scol[cl^1] + " " + wnm[p2] +" %d in city %d\n").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, ("%03d:40 blue " + wnm[b.wct[i2]] + " %d killed red " + wnm[a.wct[i1]] + " %d in city %d remaining %d elements").data(),
             ntime, i2, i1, wher, b.rsb[i2]);
            if (b.wct[i2] == 0)
            {
                s = s + t + "\n";
                sprintf(t, ("%03d:40 blue dragon %d yelled in city %d"), ntime, i2, wher);
            }
        }
        else if (dead(i2, 1) && not dead(i1, 0))
        {
            np[wher].erase(i2);
            sprintf(t, ("%03d:40 red " + wnm[a.wct[i1]] + " %d killed blue " + wnm[b.wct[i2]] + " %d in city %d remaining %d elements").data(),
             ntime, i1, i2, wher, a.rsb[i1]);
            if (a.wct[i1] == 0)
            {
                s = s + t + "\n";
                sprintf(t, ("%03d:40 red dragon %d yelled in city %d"), ntime, i1, wher);
            }
        }
        else if (dead(i1, 0) && dead(i2, 1))
        {
            np[wher].erase(-i1);
            np[wher].erase(i2);
            sprintf(t, ("%03d:40 both red " + wnm[a.wct[i1]] + " %d and blue " + wnm[b.wct[i2]] + " %d died in city %d").data(),
             ntime, i1, i2, wher);
        }
        else if (not dead(i1, 0) && not dead(i2, 1))
        {
            sprintf(t, ("%03d:40 both red " + wnm[a.wct[i1]] + " %d and blue " + wnm[b.wct[i2]] + " %d were alive in city %d").data(),
             ntime, i1, i2, wher);
            if (a.wct[i1] == 0)
            {
                s = s + t + "\n";
                sprintf(t, ("%03d:40 red dragon %d yelled in city %d"), ntime, i1, wher);
            }            
            if (b.wct[i2] == 0)
            {
                s = s + t + "\n";
                sprintf(t, ("%03d:40 blue dragon %d yelled in city %d"), ntime, i2, wher);
            }
        }
        s += t;
        cout<<s<<"\n";
        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("%03d:50 %d elements in red headquarter\n",ntime,tm[0].bld);
        printf("%03d:50 %d elements in blue headquarter\n",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(("%03d:55 "+scol[cl]+" "+wnm[a.wct[k]]+" %d has %d sword %d bomb %d arrow and %d elements\n").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("%d", &__T);
    for (int __i = 1; __i <= __T; ++__i)
    {
        scanf("%d%d%d%d", &M, &N, &K, &T);
        for (int i = 0; i < 5; ++i)
            scanf("%d", &wsb);
        for (int i = 0; i < 5; ++i)
            scanf("%d", &foc);
        init();
        printf("Case %d:\n",__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
*/
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|七游戏

GMT+8, 2025-3-15 15:45 , Processed in 0.115345 second(s), 61 queries .

Powered by Discuz! X3.4. 技术支持 by 巅峰设计

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表