您的位置:首页 > 其它

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

2015-12-19 13:24 429 查看
武林

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的时候没改过来,浪费这么多个小时简直[b]**********[/b]。

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: