武林


武林
Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3372    Accepted Submission(s): 909


Problem Description
在一个有1212列的方形的武林世界里,少林、武当和峨嵋三派的弟子们在为独霸武林而互相厮杀。武林世界的第一行的一列格子的坐标是(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
***


Source
POJ 

面向对象一下:


#include <iostream>
#include <list>
#include <set>
#include <cmath>
using namespace std;
// 1107
class DiZi
{
public:
    int m_neiLi, m_wuYi, m_shengMing;
    char m_type;
    int x, y;
    int moveDirX, moveDirY;
    list<DiZi*> (*m_wuLinShiJie)[12][12];

    DiZi() : m_wuLinShiJie(NULL)
    {

    }

    virtual double getGongJiLi() = 0;
    virtual void calcStep() = 0;
    void move()
    {
        list<DiZi*> &old = (*m_wuLinShiJie)[x][y];
        for (list<DiZi*>::iterator iter = old.begin(); iter != old.end(); ++iter)
        {
            if (*iter == this)
            {
                old.erase(iter);
                break;
            }
        }

        calcStep();
        (*m_wuLinShiJie)[x][y].push_back(this);
    }
};

class ShaoLin : public DiZi
{
public:
    ShaoLin()
    {
        moveDirX = 1;
        moveDirY = 0;
    }
    virtual double getGongJiLi()
    {
        return floor((0.5 * m_neiLi + 0.5 * m_wuYi) * (m_shengMing + 10) / 100);
    }
    virtual void calcStep()
    {
        if (moveDirX > 0)
        {
            if (x == 11)
                moveDirX = -1;
            x += moveDirX;
        }
        else if (moveDirX < 0)
        {
            if (x == 0)
                moveDirX = 1;
            x += moveDirX;
        }
    }
};

class WuDang : public DiZi
{
public:
    WuDang()
    {
        moveDirX = 0;
        moveDirY = 1;
    }
    virtual double getGongJiLi()
    {
        return floor((0.8 * m_neiLi + 0.2 * m_wuYi) * (m_shengMing + 10) / 100);
    }
    virtual void calcStep()
    {
        if (moveDirY > 0)
        {
            if (y == 11)
                moveDirY = -1;
            y += moveDirY;
        }
        else if (moveDirY < 0)
        {
            if (y == 0)
                moveDirY = 1;
            y += moveDirY;
        }
    }
};

class EMei : public DiZi
{
public:
    EMei()
    {
        moveDirX = 1;
        moveDirY = 1;
    }
    virtual double getGongJiLi()
    {
        return floor((0.2 * m_neiLi + 0.8 * m_wuYi) * (m_shengMing + 10) / 100);
    }
    virtual void calcStep()
    {
        if ((x == 0 && y == 11) || (x == 11 && y == 0))
            return;

        if (moveDirX > 0)
        {
            if (x == 11)
            {
                moveDirX = -1;
                moveDirY = -moveDirY;
            }
            else if (moveDirY > 0 && y == 11)
            {
                moveDirX = -moveDirX;
                moveDirY = -moveDirY;
            }
            else if (moveDirY < 0 && y == 0)
            {
                moveDirX = -moveDirX;
                moveDirY = -moveDirY;
            }
            x += moveDirX;
            y += moveDirY;
        }
        else if (moveDirX < 0)
        {
            if (x == 0)
            {
                moveDirX = 1;
                moveDirY = -moveDirY;
            }
            else if (moveDirY > 0 && y == 11)
            {
                moveDirX = -moveDirX;
                moveDirY = -moveDirY;
            }
            else if (moveDirY < 0 && y == 0)
            {
                moveDirX = -moveDirX;
                moveDirY = -moveDirY;
            }
            x += moveDirX;
            y += moveDirY;
        }
    }
};

int main()
{
    int n = 0;
    while (cin >> n)
    {
        for (int i = 0; i < n; ++i)
        {
            list<DiZi*> wuLinShiJie[12][12];
            set<DiZi*> diZiSet;
            int step = 0;
            cin >> step;
            char type;
            while (cin >> type)
            {
                if (type == '0')
                    break;
                DiZi *d = NULL;
                switch (type)
                {
                case 'S':
                    d = new ShaoLin;
                    break;
                case 'W':
                    d = new WuDang;
                    break;
                case 'E':
                    d = new EMei;
                    break;
                }

                d->m_type = type;
                cin >> d->x >> d->y >> d->m_neiLi >> d->m_wuYi >> d->m_shengMing;
                d->m_wuLinShiJie = &wuLinShiJie;
                --d->x;
                --d->y;
                wuLinShiJie[d->x][d->y].push_back(d);
                diZiSet.insert(d);
            }

            for (int j = 0; j < step; ++j)
            {
                for (int a = 0; a < 12; ++a)
                {
                    for (int b = 0; b < 12; ++b)
                    {
                        list<DiZi*> &l = wuLinShiJie[a][b];
                        if (l.size() != 2)
                            continue;
                        if (l.front()->m_type == l.back()->m_type)
                            continue;
                        int fg = (int)l.front()->getGongJiLi();
                        int bg = (int)l.back()->getGongJiLi();
                        l.front()->m_shengMing -= bg;
                        l.back()->m_shengMing -= fg;
                        if (l.front()->m_shengMing <= 0)
                        {
                            diZiSet.erase(l.front());
                            delete l.front();
                            l.pop_front();
                        }
                        if (l.back()->m_shengMing <= 0)
                        {
                            diZiSet.erase(l.back());
                            delete l.back();
                            l.pop_back();
                        }
                    }
                }

                for (set<DiZi*>::iterator iter = diZiSet.begin(); iter != diZiSet.end(); ++iter)
                {
                    DiZi *d = *iter;
                    d->move();
                }
            }

            int sc = 0, wc = 0, ec = 0;
            int ss = 0, ws = 0, es = 0;

            for (set<DiZi*>::iterator iter = diZiSet.begin(); iter != diZiSet.end(); ++iter)
            {
                DiZi *d = *iter;
                if (d->m_type == 'S')
                {
                    ++sc;
                    ss += d->m_shengMing;
                }
                else if (d->m_type == 'W')
                {
                    ++wc;
                    ws += d->m_shengMing;
                }
                else if (d->m_type == 'E')
                {
                    ++ec;
                    es += d->m_shengMing;
                }
                delete d;
            }

            cout << sc << ' ' << ss << endl;
            cout << wc << ' ' << ws << endl;
            cout << ec << ' ' << es << endl;
            printf("***\n");
        }
    }
return 0;
}

个人代码:

#include <iostream>
#include <string.h>
using namespace std;
int map1[13][13][13];//1E
int map2[13][13][13];//2S
int map3[13][13][13];//3W
const int dir1[][2]={{1,1},{-1,-1}};//峨眉
const int dir2[][2]={{1,0},{-1,0}};//少林
const int dir3[][2]={{0,1},{0,-1}};//武当
struct  object
{
  int x,y;//坐标
  int m,n;//攻击力,生命值
  int school;//1是E,2是S,3是W
  bool flag;
};
bool borden(int x,int dir)
{
   return  (x+dir)==13||(x+dir)==0;
}


void sov()
{
    memset(map1,0,sizeof(map1));
    memset(map2,0,sizeof(map2));
    memset(map3,0,sizeof(map3));
    int N;
    char ch;
    object Em[200],Wd[200],Sl[200];
    int e=1,w=1,s=1;
    int x,y,m1,m2,m3;
    int n1=0,n2=0,n3=0;
    bool b;
    int i,j;
    scanf("%d",&N);
    while(1)
    {
    scanf(" %c",&ch);
    if(ch=='0')break;
    scanf("%d%d%d%d%d",&x,&y,&m1,&m2,&m3);
     if(ch=='E')
    {
        m1= (0.2 * m1 + 0.8 * m2) * (m3 + 10) / 100;
        Em[e].x=x;Em[e].y=y;
        Em[e].m=m1;Em[e].n=m3;
        Em[e].school=1;
        Em[e].flag=false;
        n1=0;
        while(map1[x][y][n1]!=0){n1++;}
        map1[x][y][n1]=e++;
    }
    if(ch=='S')
    {
        m1= (0.5 * m1 + 0.5 * m2) * (m3 + 10) / 100;
        Sl[s].x=x;Sl[s].y=y;
        Sl[s].m=m1;Sl[s].n=m3;
        Sl[s].school=2;
        Sl[s].flag=false;
        n2=0;
        while(map2[x][y][n2]!=0) {n2++;}
        map2[x][y][n2]=s++;
    }
     if(ch=='W')
    {
        m1= (0.8 * m1 + 0.2 * m2) * (m3 + 10) / 100;
        Wd[w].x=x;Wd[w].y=y;
        Wd[w].m=m1;Wd[w].n=m3;
        Wd[w].school=3;
        Wd[w].flag=false;
        n3=0;
        while(map3[x][y][n3]!=0){n3++;}
        map3[x][y][n3]=w++;
    }


    }

   while(N--)
   {
//更新人的生命值
for(i=1;i<=12;i++)
 for(j=1;j<=12;j++)
{
    if(map1[i][j][0]&&!map1[i][j][1]&&map2[i][j][0]&&!map2[i][j][1]&&!map3[i][j][0])
    {
     x=map1[i][j][0];
     y=map2[i][j][0];
     Em[x].n-=Sl[y].m;
     if(Em[x].n<=0){Em[x].school=-1;}
     Sl[y].n-=Em[x].m;
     if(Sl[y].n<=0){Sl[y].school=-1;}

    }
      if(map1[i][j][0]&&!map1[i][j][1]&&!map2[i][j][0]&&map3[i][j][0]&&!map3[i][j][1])
    {
     x=map1[i][j][0];
     y=map3[i][j][0];
     Em[x].n-=Wd[y].m;
     if(Em[x].n<=0){Em[x].school=-1;}
     Wd[y].n-=Em[x].m;
     if(Wd[y].n<=0){Wd[y].school=-1;}

    }
    if(!map1[i][j][0]&&map2[i][j][0]&&!map2[i][j][1]&&map3[i][j][0]&&!map3[i][j][1])
    {
     x=map2[i][j][0];
     y=map3[i][j][0];
     Sl[x].n-=Wd[y].m;
     if(Sl[x].n<=0){Sl[x].school=-1;}
     Wd[y].n-=Sl[x].m;
     if(Wd[y].n<=0){Wd[y].school=-1;}

    }


}

//更新地图
memset(map1,0,sizeof(map1));
memset(map2,0,sizeof(map2));
memset(map3,0,sizeof(map3));
int e1=0,w1=0,s1=0;   
for(i=1;i<=e;i++)
{
if(Em[i].school==-1)continue;
b=Em[i].flag;
if(borden(Em[i].x,dir1[b][0])||borden(Em[i].y,dir1[b][1]))
{
b=Em[i].flag=!Em[i].flag;
Em[i].x+=dir1[b][0];
Em[i].y+=dir1[b][1];
}
else {Em[i].x+=dir1[b][0];Em[i].y+=dir1[b][1];}
e1=0;
while(map1[Em[i].x][Em[i].y][e1]!=0){e1++;} map1[Em[i].x][Em[i].y][e1]=i;
}
for(i=1;i<=s;i++)
{
if(Sl[i].school==-1)continue;
b=Sl[i].flag;
if(borden(Sl[i].x,dir2[b][0])||borden(Sl[i].y,dir2[b][1]))
{
b=Sl[i].flag=!Sl[i].flag;
Sl[i].x+=dir3[b][0];
Sl[i].y+=dir3[b][1];
}
else {Sl[i].x+=dir2[b][0];Sl[i].y+=dir2[b][1];}
s1=0;
while(map2[Sl[i].x][Sl[i].y][s1]!=0){s1++;}map2[Sl[i].x][Sl[i].y][s1]=i;
} 

for(i=1;i<=w;i++)
{
if(Wd[i].school==-1) continue;
b=Wd[i].flag;
if(borden(Wd[i].x,dir3[b][0])||borden(Wd[i].y,dir3[b][1]))
{
b=Wd[i].flag=!Wd[i].flag;
Wd[i].x+=dir3[b][0];
Wd[i].y+=dir3[b][1];
}
else {Wd[i].x+=dir3[b][0];Wd[i].y+=dir3[b][1];}
w1=0;
while(map3[Wd[i].x][Wd[i].y][w1]!=0){w1++;}map3[Wd[i].x][Wd[i].y][w1]=i;

}

}
//while 结束
int e2=0,w2=0,s2=0;
int sum1=0,sum2=0,sum3=0;
for(i=1;i<=e;i++)
{
if(Em[i].school==-1)continue;
e2++;
sum1+=Em[i].n;
}
for(i=1;i<=s;i++)
{
if(Sl[i].school==-1)continue;
s2++;
sum2+=Sl[i].n;
}
for(i=1;i<=w;i++)
{
printf("%d %d\n",s2,sum2);
if(Wd[i].school==-1)continue;
w2++;
sum3+=Wd[i].n;
}
printf("%d %d\n",w2,sum3);
printf("%d %d\n",e2,sum1);
printf("***\n");

}
int main()
{
    int T;
scanf("%d",&T);
while(T--)
  sov();


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值