【HDU1107】【模拟】武林 三个门派来回走定制方向单挑架

来源:互联网 发布:java创建服务器 编辑:程序博客网 时间:2024/05/17 04:58
#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|1typedef 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步之后,每个派别剩下的人数和生命值之和。【类型】模拟【分析】模拟要学会简化问题,要学会归类*/


1 0
原创粉丝点击