HDU 1107 武林 大模拟

题目https://cn.vjudge.net/problem/HDU-1107

题意:中文题干不再赘述,仅强调两处细节
(1)仅当一个格子里有两名弟子,且二者分属不同门派时才会发生战斗。
(2)每次战斗+移动称作一步,最后一次移动后的战斗不需处理。

思路:模拟题怎么写都能写出来,我提供几处的实现方法供参考。
(1)存储结构:滚动二维结构体数组,相当于两个二维数组,移动时将属性改变后的结构体放入新二维数组,清空旧二维数组。

(2)移动:在结构体内设dr,dc两成员变量分别表示行列上移动距离和方向,根据门派进行不同的初始化(少林弟子dr=1,dc=0;武当弟子dr=0,dc=1;峨眉弟子dr=1,dc=1;左下角右上角的峨眉弟子永远不会动dr=dc=0),每次移动时仅需判断是否触碰边界,进行反向,而不需对每种门派单独处理。

代码:C++11

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <stack>
using namespace std;

const int maxn = 20;
int n, m = 12, T;

struct Person
{
    int r, c;
    char type;
    int hp, in, vio;
    int dr, dc;
    Person(int r, int c, char type, int in, int vio, int hp): r(r), c(c), type(type), hp(hp), in(in), vio(vio)
    {
        dr = dc = 1;
        if(type == 'S')
            dc = 0;
        if(type == 'W')
            dr = 0;
        if(type == 'E' && ((r == m && c == 1) || (r == 1 && c == m)))
            dr = dc = 0;
    }
    int getatk()
    {
        if(type == 'S')
        {
            return (0.5 * in + 0.5 * vio) * (hp + 10.0) / 100;
        }
        else if(type == 'W')
        {
            return (0.8 * in + 0.2 * vio) * (hp + 10.0) / 100;
        }
        else if(type == 'E')
        {
            return (0.2 * in + 0.8 * vio) * (hp + 10.0) / 100;
        }
    }
    Person move()
    {
        #define inpic(r, c) (r >= 1 && r <= m && c >= 1 && c <= m)
        if(!inpic(r + dr, c + dc))
        {
            dr = -dr;
            dc = -dc;
        }
        r += dr;
        c += dc;
        return *this;
    }
};

vector<Person> pic[2][maxn][maxn];

void clear(int p)
{
    for(int i = 0; i < maxn; i++)
    {
        for(int j = 0; j < maxn; j++)
        {
            pic[p][i][j].clear();
        }
    }
}

inline bool battlecheck(vector<Person> &v)
{
    if(v.size() != 2)
        return false;
    return v[0].type != v[1].type;
}

void battle(int p)
{
    auto &upic = pic[p];
    for(int i = 1; i <= m; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            if(battlecheck(upic[i][j]))
            {
                int atk0 = upic[i][j][0].getatk();
                int atk1 = upic[i][j][1].getatk();
                upic[i][j][0].hp -= atk1;
                upic[i][j][1].hp -= atk0;
            }
        }
    }
}

void move(int p, int tp)
{
    for(int i = 1; i <= m; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            for(auto &t : pic[p][i][j])
            {
                if(t.hp > 0)
                {
                    Person np = t.move();
                    pic[tp][np.r][np.c].push_back(np);
                }
            }
        }
    }
}

void solve()
{
    int p = 0;
    for(int cnt = 0; cnt < T; cnt++)
    {
        int tp = (p + 1) % 2;
        battle(p);
        move(p, tp);
        clear(p);
        p = tp;
    }
    int scnt = 0, wcnt = 0, ecnt = 0;
    int shp = 0, whp = 0, ehp = 0;
    for(int i = 1; i <= m; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            for(auto &t : pic[p][i][j])
            {
                if(t.hp <= 0)
                    continue;
                if(t.type == 'S')
                {
                    scnt++;
                    shp += t.hp;
                }
                else if(t.type == 'W')
                {
                    wcnt++;
                    whp += t.hp;
                }
                else if(t.type == 'E')
                {
                    ecnt++;
                    ehp += t.hp;
                }
            }
        }
    }
    cout << scnt << " " << shp << endl;
    cout << wcnt << " " << whp << endl;
    cout << ecnt << " " << ehp << endl;
    cout << "***" << endl;
}

int main()
{
    ios::sync_with_stdio(false);
    int cases;
    cin >> cases;
    while(cases--)
    {
        clear(0);
        clear(1);
        cin >> T;
        char type;
        while(cin >> type && type != '0')
        {
            int r, c, in, vio, hp;
            cin >> r >> c >> in >> vio >> hp;
            pic[0][r][c].push_back(Person(r, c, type, in, vio, hp));
        }
        solve();
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值