题目:

 

武林
Time Limit:1000MS  Memory Limit:65536K
Total Submit:760 Accepted:289

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

acm 2785



少林派弟子总是在同一列回不停地行走。先往下走,走到头不能再走时就往上走,再到头则又往下走……比如,(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
***

我的解法:


#include "stdafx.h"
#include 
<stdio.h>

enum MenPai
{
    WuDang 
=0,
    ShaoLin 
=1,
    EMei 
=2,
};

enum Direction
{
    Forward 
= 0,
    Back 
= 1,
};

double nx[3= {0.8,0.5,0.2};
double wx[3= {0.2,0.5,0.8};
typedef 
struct item2
{
    
int x,y;
}Position;

typedef 
struct item4
{
    
int person;
    
int life;
}Result;

typedef 
struct item
{
    MenPai mp;
    
int neili;
    
int wuyi;
    
int life;
    
double attack;
    Direction d;
    
bool still;
    
struct item*next;
}Person,
*LPerson;

typedef 
struct item3
{
    LPerson head;
    
int count;
}T;
T t[
12][12];

Position pos[
3][2= {0,1,0,-1,1,0,-1,0,1,1,-1,-1}; 

void Init()
{
    
for(int i = 0;i < 12;i++)
        
for(int j = 0;j < 12;j++)
        {
            t[i][j].count 
= 0;
            t[i][j].head 
= NULL;
        }
}

void AddPerson(char* tf)
{
    
char dh;
    
int row,col;
    
int neili,wuyi,life;

    sscanf(tf,
"%c%d%d%d%d%d",&dh,&row,&col,&neili,&wuyi,&life);

    LPerson p 
= new Person;
    p
->next = NULL;
    p
->life = life;
    p
->neili = neili;
    p
->wuyi = wuyi;
    p
->= Forward;
    p
->still = false;
    
switch(dh)
    {
    
case 'S':
        p
->mp = ShaoLin;
        p
->attack = (0.5*neili + 0.5*wuyi)*(life+10)/100;
        
break;
    
case 'W':
        p
->mp = WuDang;
        p
->attack = (0.8*neili + 0.2*wuyi)*(life+10)/100;
        
break;
    
case 'E':
        
if((row == 12 && col == 1|| (row == 1 && col == 12))
            p
->still = true;
        p
->mp = EMei;
        p
->attack = (0.8*neili + 0.2*wuyi)*(life+10)/100;
        
break;
    }
    t[row
-1][col-1].count++;
    
if(t[row-1][col-1].head == NULL)
    {
        t[row
-1][col-1].head = p;
    }
    
else
    {
        p
->next = t[row-1][col-1].head->next;
        t[row
-1][col-1].head->next = p;
    }
    
}

void Attack()
{
    
for(int i = 0;i<12;i++)
    {
        
for(int j = 0;j < 12;j++)
        {
            
if(t[i][j].count == 2)            //该方格有两人
            {
                LPerson p1 
= t[i][j].head;
                LPerson p2 
= p1->next;

                
if(p1->mp != p2->mp)        //不是同一门派的,战斗
                {
                    p1
->life -= (int)p2->attack;
                    p2
->life -= (int)p1->attack;

                    
if(p1->life <= 0)        //死了
                    {
                        t[i][j].count
--;
                        t[i][j].head 
= p2;
                        delete p1;
                        p1 
= NULL;
                    }
                    
else
                        p1
->attack = (nx[p1->mp]*p1->neili + wx[p1->mp]*p1->wuyi)*(p1->life + 10)/100;
                    
if(p2->life <= 0)
                    {
                        t[i][j].count
--;
                        t[i][j].head 
= p1;
                        delete p2;
                        p2 
= NULL;
                    }
                    
else
                        p2
->attack = (nx[p2->mp]*p2->neili + wx[p2->mp]*p2->wuyi)*(p2->life + 10)/100;
                }
            }
        }
    }
}

void Move()
{
    
int i,j;
    T temp[
12][12];
    
for(i = 0;i < 12;i++)
    {
        
for(j = 0;j < 12;j++)
        {
            temp[i][j].count 
= 0;
            temp[i][j].head 
= NULL;
        }
    }
    
    
for(i = 0;i < 12;i++)
    {
        
for(j = 0;j < 12;j++)
        {
            
if(t[i][j].count >0)  //有人才移动
            {
                LPerson p 
= t[i][j].head;
                LPerson q 
= p;
                
while(q != NULL)
                {
                    p 
= q;
                    q 
= q->next; 
    
                    
int r,c;
                    r 
= i+pos[p->mp][p->d].x;
                    c 
= j+pos[p->mp][p->d].y;
                    
if( r < 0 || r >11 || c < 0 || c >11//出界,往回走
                    {
                        
int kk = !((int)p->d);
                        p
->= (Direction)kk;
                        r 
= i+pos[p->mp][p->d].x;
                        c 
= j+pos[p->mp][p->d].y;
                        
if( r < 0 || r > 11 || c < 0 || c > 11//只能呆住不动
                        {
                            r 
= i;
                            c 
= j;
                        }
                    }
                    temp[r][c].count
++;
                    
if(temp[r][c].head == NULL)
                    {
                        temp[r][c].head 
= p;
                        p
->next = NULL;
                    }
                    
else
                    {
                        p
->next = temp[r][c].head->next; 
                        temp[r][c].head
->next = p;
                    }
                }
            }

        }
    }

    Init();
    
for(i = 0;i < 12;i++)
    {
        
for(j = 0;j<12;j++)
        {
            
if(temp[i][j].count > 0)
            {
                t[i][j].count 
= temp[i][j].count;
                t[i][j].head 
= temp[i][j].head;
            }
        }
    }
}

void Print()
{
    Result r[
3];
    
int i,j;
    
for(i = 0;i < 3;i++)
    {
        r[i].life 
= 0;
        r[i].person 
= 0;
    }
    
for(i = 0;i < 12;i++)
    {
        
for(j = 0;j < 12;j++)
        {
            
if(t[i][j].count > 0// 有人
            {
                LPerson p 
= t[i][j].head;
                
while(p)
                {
                    
switch(p->mp)
                    {
                    
case ShaoLin:
                        r[
0].person++;
                        r[
0].life += p->life;
                        
break;
                    
case WuDang:
                        r[
1].person++;
                        r[
1].life += p->life;
                        
break;
                    
case EMei:
                        r[
2].person++;
                        r[
2].life += p->life;
                        
break;
                    }
                    p 
= p->next;
                }
            }
        }
    }
    
for(i = 0;i < 3;i++)
        printf(
"%d %d\n",r[i].person,r[i].life);
    printf(
"***\n");
}
int main(int argc, char* argv[])
{
    
int n;
    
int m;
    
char temp[30];
    
    scanf(
"%d",&n);
    
while(n--)
    {
        Init();
        scanf(
"%d",&m);
        getchar();
        
while(1)
        {
            gets(temp);
            
if(temp[0== '0')
                
break;
            AddPerson(temp);
        }
        
        
for(int i=0;i < m;i++)
        {
            Attack();
            Move();            
//移动
        }
        Print();
    }
    
return 0;
}

相关文章:

  • 2021-10-27
  • 2021-06-10
  • 2021-10-20
  • 2022-12-23
  • 2021-08-10
  • 2021-06-30
  • 2022-01-12
  • 2022-12-23
猜你喜欢
  • 2021-08-15
  • 2022-01-02
  • 2021-11-11
  • 2021-09-21
  • 2022-12-23
  • 2022-12-23
  • 2021-10-28
相关资源
相似解决方案