HdU OJ 1107 武林 一只巨大的模拟

武林

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3083 Accepted Submission(s): 819

Problem Description
在一个有12行12列的方形的武林世界里,少林、武当和峨嵋三派的弟子们在为独霸武林而互相厮杀。武林世界的第一行的一列格子的坐标是(1, 1),第一行第二列坐标是(1, 2)……右下角的坐标为(12, 12)。如图:

这里写图片描述
少林派弟子总是在同一列回不停地行走。先往下走,走到头不能再走时就往上走,再到头则又往下走……比如,(1, 1) -> (2, 1) -> (3, 1)。
武当派弟子总是在同一行来回不停地行走。先往右走,走到头不能再走时就往左走,再到头则又往右走……比如,(2, 1) -> (2, 2) -> (2, 3)。
峨嵋派弟子总是在右下-左上方向来回不停走,先往右下方走,走到头不能再走时就往左上方走,再到头则又往右下方走……比如,(1, 1) -> (2, 2) -> (3, 3)。峨嵋弟子如果位于(1,12)或(12,1),那当然只能永远不动。

每次走动,每个弟子必须,而且只能移动一个格子。
每名弟子有内力、武艺、和生命力三种属性。这三种属性的取值范围都是大于等于0,小于等于100。

当有两名不同门派的弟子进入同一个格子时,一定会发生一次战斗,而且也只有在这种情况下,才会发生战斗。(同派弟子之间当然不会自相残杀;一个格子里三派弟子都有时,大家都会因为害怕别人渔翁得利而不敢出手;而多名同门派弟子也不会联手对付敌人,因为这有悖于武林中崇尚的单打独斗精神,会被人耻笑)

一次战斗的结果将可能导致参战双方生命力发生变化,计算方法为:

战后生命力 = 战前生命力 - 对方攻击力

而不同门派的弟子攻击力计算方法不同:

少林派攻击力 = (0.5 * 内力 + 0.5 * 武艺) * (战前生命力 + 10) / 100
武当派攻击力 = (0.8 * 内力 + 0.2 * 武艺) * (战前生命力 + 10) / 100
峨嵋派攻击力 = (0.2 * 内力 + 0.8 * 武艺) * (战前生命力 + 10) / 100

对攻击力的计算过程为浮点运算,最终结果去掉小数点后部分取整,使得攻击力总是整数。
一次战斗结束后,生命力变为小于或等于0的弟子,被视为“战死”,会从武林中消失。
两名不同门派的弟子相遇时,只发生一次战斗。

初始状态下,不存在生命值小于或等于0的弟子,而且一个格子里有可能同时有多个弟子。
一系列战斗从初始状态就可能爆发,全部战斗结束后,仍然活着的弟子才开始一齐走到下一个格子。总之,不停地战斗-行走-战斗-行走……所有弟子都需等战斗结束后,才一齐走到下一个格子。
你需要做的是,从一个初始状态,算出经过N步(N < 1000)后的状态。所有的弟子先进行完全部战斗(当然也可能没有任何战斗发生),然后再一齐走到下一个格子,这称为一步。
所有弟子总数不会超过1000。

Input
第一行是测试数据的组数,随后是各组测试数据。
每组数据第一行是行走步数 N。
接下来的若干行,每行描述一名弟子的位置及其各项参数。描述弟子时,格式为“弟子代号 行号 列号 内力 武艺 生命力”。弟子代号就是一个字母:
‘S’ 代表少林派弟子
‘W’ 代表武当派弟子
‘E’ 代表峨嵋派弟子

比如:
W 10 2 10 3 10
表示第10行第2列有一名武当派弟子,他的内力是 10,武艺是3,生命力是10。

每组测试数据以一个结束标志行结尾。结束标志行只含有一个字符’0’。

Output
针对每组测试数据,您的输出应该是4行,前3行每行是用空格分隔的两个整数,前一个是某派弟子总数,后一个是本派所有弟子生命力之和。规定第1行代表少林派,第2行代表武当派,第3行代表峨嵋派。第4行是 “*”表示结束。

Sample Input
2
1
S 1 2 20 20 20
W 2 1 20 20 20
0
2
S 1 2 20 20 20
W 2 1 20 20 20
E 12 12 20 20 100
0

Sample Output
1 20
1 20
0 0
三个*
1 14
1 14
1 100
三个*

巨大模拟,本人弱菜,怕写错把很多步骤都分开写,采用了小键盘记录方向的方法来记录往哪边走。注意好几个细节就可以了,峨眉走的时候点(1,12)和(12,1)不动,还有方向变换和步数的加减。写完重头看一下是否有变量写错了的情况。

还有记得看自己的变量的类型定义错了没(友好的笑脸),我居然把wuyi改成double的时候没改过来,浪费这么多个小时简直**********

CODE

#include"stdio.h"
#include"iostream"
#include"algorithm"
#include"string.h"
#include"math.h"
#include"stdlib.h"
#include"queue"
#include"vector"
const int maxn = 1000+10;
using namespace std;

struct node
{
    char mp;
    int x,y;
    int neili;  ///踏马这里居然写成double没去检查,检查一万遍,我*****
    int wuyi;
    int life;
    int dir;   ///4,6代表左右  8,2代表上下 3,7代表右下左上
}dz[maxn];
int n;
int cnt;       ///弟子数量
int ansp[10];   ///存活人数
int ansl[10];   ///总的生命值
int maze[20][20];

void init()
{
    memset(maze,0,sizeof maze);
    memset(ansl,0,sizeof ansl);
    memset(ansp,0,sizeof ansp);
}

int hurts(int num) ///少林伤害
{
    return (0.5*dz[num].neili+0.5*dz[num].wuyi)*(dz[num].life+10)/100;
}

int hurtw(int num) ///武当伤害
{
    return (0.8*dz[num].neili+0.2*dz[num].wuyi)*(dz[num].life+10)/100;
}

int hurte(int num) ///峨眉伤害
{
    return (0.2*dz[num].neili+0.8*dz[num].wuyi)*(dz[num].life+10)/100;
}

void sha(int x,int y)
{
    int t1,t2;
    int temp = 0;
    for(int i = 0;i < cnt;i++)
    {
        if(dz[i].x == x && dz[i].y == y && dz[i].life > 0)
        {
            if(temp == 0)
                t1 = i;
            else
                t2 = i;
            temp++;
        }
        if(temp == 2)
            break;
    }
    if(dz[t1].mp == dz[t2].mp) return;
    int hurt1,hurt2;
    if(dz[t1].mp == 'S')
        hurt1 = hurts(t1);
    else if(dz[t1].mp == 'W')
        hurt1 = hurtw(t1);
    else if(dz[t1].mp == 'E')
        hurt1 = hurte(t1);
    if(dz[t2].mp == 'S')
        hurt2 = hurts(t2);
    else if(dz[t2].mp == 'W')
        hurt2 = hurtw(t2);
    else if(dz[t2].mp == 'E')
        hurt2 = hurte(t2);
    dz[t1].life -= hurt2;
    dz[t2].life -= hurt1;
    if(dz[t1].life <= 0)
    {
        dz[t1].life = 0;
        maze[dz[t1].x][dz[t1].y]--;
    }
    if(dz[t2].life <= 0)
    {
        dz[t2].life = 0;
        maze[dz[t2].x][dz[t2].y]--;
    }
}

void shashasha()
{
    for(int i = 1;i <= 12;i++)
    {
        for(int j = 1;j <= 12;j++)
        {
            if(maze[i][j] == 2)
            {
                sha(i,j);
            }
        }
    }
}

void shaolinzou(int i)  ///少林走
{
    if(dz[i].dir == 2)
    {
        if(dz[i].x == 12)
        {
            dz[i].x--;
            dz[i].dir = 8;
        }
        else
            dz[i].x++;
    }
    else
    {
        if(dz[i].x == 1)
        {
            dz[i].x++;
            dz[i].dir = 2;
        }
        else
            dz[i].x--;
    }
}

void wudangzou(int i)   ///武当走
{
    if(dz[i].dir == 6)
    {
        if(dz[i].y == 12)
        {
            dz[i].y--;
            dz[i].dir = 4;
        }
        else
            dz[i].y++;
    }
    else
    {
        if(dz[i].y == 1)
        {
            dz[i].y++;
            dz[i].dir = 6;
        }
        else
            dz[i].y--;
    }
}

void emeizou(int i)   ///峨眉走
{
    if((dz[i].x == 1 && dz[i].y == 12) || (dz[i].x == 12 && dz[i].y == 1))
        return;
    maze[dz[i].x][dz[i].y]--;
    if(dz[i].dir == 3)
    {
        if(dz[i].x == 12 || dz[i].y == 12)
        {
            dz[i].x--;
            dz[i].y--;
            dz[i].dir = 7;
        }
        else
        {
            dz[i].x++;
            dz[i].y++;
        }
    }
    else// dir==7
    {
        if(dz[i].x == 1 || dz[i].y == 1)
        {
            dz[i].x++;
            dz[i].y++;
            dz[i].dir = 3;
        }
        else
        {
            dz[i].x--;
            dz[i].y--;
        }
    }
    maze[dz[i].x][dz[i].y]++;
}

void zouzouzou()
{
    for(int i = 0;i < cnt;i++)
    {
        if(dz[i].life > 0)
        {
            if(dz[i].mp == 'S')
            {
                maze[dz[i].x][dz[i].y]--;
                shaolinzou(i);
                maze[dz[i].x][dz[i].y]++;
            }
            else if(dz[i].mp == 'W')
            {
                maze[dz[i].x][dz[i].y]--;
                wudangzou(i);
                maze[dz[i].x][dz[i].y]++;
            }
            else if(dz[i].mp == 'E')
            {
                emeizou(i);
            }
        }
    }
}

int main(void)
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        init();
        scanf("%d",&n);
        char ss[10];
        int x,y;
        int nei,wu,lif;
        cnt = 0;
        while(scanf("%s",ss) && ss[0] != '0')
        {
            scanf("%d%d%d%d%d",&x,&y,&nei,&wu,&lif);
            dz[cnt].mp = ss[0];
            dz[cnt].x = x;
            dz[cnt].y = y;
            dz[cnt].neili = nei;
            dz[cnt].wuyi = wu;
            dz[cnt].life = lif;
            if(dz[cnt].mp == 'S')
                dz[cnt].dir = 2;
            if(dz[cnt].mp == 'W')
                dz[cnt].dir = 6;
            if(dz[cnt].mp == 'E')
                dz[cnt].dir = 3;
            maze[x][y]++;
            cnt++;
        }
        while(n--)
        {
            shashasha();
            zouzouzou();
        }
        ///shashasha();
        for(int i = 0;i < cnt;i++)
        {
            if(dz[i].life > 0)
            {
                if(dz[i].mp == 'S') {ansp[0]++; ansl[0]+=dz[i].life;}
                if(dz[i].mp == 'W') {ansp[1]++; ansl[1]+=dz[i].life;}
                if(dz[i].mp == 'E') {ansp[2]++; ansl[2]+=dz[i].life;}
            }
            ///printf("%d  %d  %d  %d  %d\n",dz[i].x,dz[i].y,dz[i].neili,dz[i].wuyi,dz[i].life);
        }
        for(int i = 0;i < 3;i++)
        {
            printf("%d %d\n",ansp[i],ansl[i]);

        }
        printf("***\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值