#include<stdio.h> #include<string.h> #include<ctype.h> #include<math.h> #include<iostream> #include<string> #include<set> #include<map> #include<vector> #include<queue> #include<bitset> #include<algorithm> #include<time.h> using namespace std; void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);} #define MS(x,y) memset(x,y,sizeof(x)) #define MC(x,y) memcpy(x,y,sizeof(x)) #define MP(x,y) make_pair(x,y) #define ls o<<1 #define rs o<<1|1 typedef long long LL; typedef unsigned long long UL; typedef unsigned int UI; template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;} template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;} const int N=1010,M=0,Z=1e9+7,ms63=1061109567; int casenum,casei; int n,m; struct A { int typ; double atk; int y,x,hp; int d; }a[N]; int b[14][14][3]; int num[3],hp[3]; int main() { scanf("%d",&casenum); for(casei=1;casei<=casenum;casei++) { scanf("%d",&m);n=0; char ch;int atk1,atk2; while(scanf(" %c",&ch),ch!='0') { ++n;scanf("%d%d%d%d%d",&a[n].y,&a[n].x,&atk1,&atk2,&a[n].hp); a[n].d=1; if(ch=='S') { a[n].typ=0; a[n].atk=0.005*atk1+0.005*atk2; } else if(ch=='W') { a[n].typ=1; a[n].atk=0.008*atk1+0.002*atk2; } else { a[n].typ=2; a[n].atk=0.002*atk1+0.008*atk2; } } for(int i=1;i<=m;i++) { MS(b,0); for(int j=1;j<=n;j++)if(a[j].hp>0) { if(b[a[j].y][a[j].x][0]==0)b[a[j].y][a[j].x][0]=j; else if(b[a[j].y][a[j].x][1]==0)b[a[j].y][a[j].x][1]=j; else b[a[j].y][a[j].x][2]=j; if(a[j].typ==0) { if(a[j].y==1)a[j].d=1; else if(a[j].y==12)a[j].d=-1; a[j].y+=a[j].d; } else if(a[j].typ==1) { if(a[j].x==1)a[j].d=1; else if(a[j].x==12)a[j].d=-1; a[j].x+=a[j].d; } else { if(a[j].y==12&&a[j].x==1||a[j].y==1&&a[j].x==12)a[j].d=0; else if(a[j].y==1||a[j].x==1)a[j].d=1; else if(a[j].y==12||a[j].x==12)a[j].d=-1; a[j].y+=a[j].d; a[j].x+=a[j].d; } } for(int j=1;j<=12;j++) { for(int k=1;k<=12;k++) { if(b[j][k][2]==0&&b[j][k][1]!=0) { int p1=b[j][k][0]; int p2=b[j][k][1]; if(a[p1].typ!=a[p2].typ) { //一定要先算完攻击力后再把影响生效 int atk1=a[p1].atk*(a[p1].hp+10); int atk2=a[p2].atk*(a[p2].hp+10); a[p1].hp-=atk2; a[p2].hp-=atk1; } } } } } MS(num,0); MS(hp,0); for(int j=1;j<=n;j++)if(a[j].hp>0) { ++num[a[j].typ]; hp[a[j].typ]+=a[j].hp; } for(int i=0;i<3;i++)printf("%d %d\n",num[i],hp[i]); puts("***"); } return 0; } /* 【trick&&吐槽】 1,是先战斗再移动,顺序不要错 2,移动是有方向性的,要好好判定。 【题意】 给你一个12*12的棋盘 有n(1000)个人在棋盘中无限地走来走去。 人有三种—— 1,S少林派,每次竖着走,走到头会再返回…… 2,W武当派,每次横着走,走到头会再返回…… 3,E峨眉派,每次斜着走,走到头会再返回…… 告诉你每个人的—— 派别,行号,列号,魔法攻击力,物理攻击力,初始生命值 少林派攻击力 = (0.5 * 内力 + 0.5 * 武艺) * (战前生命力 + 10) / 100 武当派攻击力 = (0.8 * 内力 + 0.2 * 武艺) * (战前生命力 + 10) / 100 峨嵋派攻击力 = (0.2 * 内力 + 0.8 * 武艺) * (战前生命力 + 10) / 100 然后我们要操作m步, 首先,如果一个位置恰有2个人,且这2个人属于不同的派别,那么这2个人会打一架。 然后,每个活着的人前进一步。 问你,经过这3步之后,每个派别剩下的人数和生命值之和。 【类型】 模拟 【分析】 模拟要学会简化问题,要学会归类 */