欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

洛谷 P5506 *

程序员文章站 2022-06-24 08:52:08
[TOC] 题目 "P5506 *" 思路 模拟 $\large\text{读题一定要细心}$ 解释都在代码里。 $Code$ cpp include define MAXN 101 using namespace std; int n,t; struct qwq{ int dx,dy,dz; } ......

目录


题目

p5506 *

思路

模拟
$\large\text{读题一定要细心}$
解释都在代码里。

$code$

#include<bits/stdc++.h>
#define maxn 101
using namespace std;
int n,t;
struct qwq{
    int dx,dy,dz;
}movebz[5][8];//用于存储f、h对应的正前方
struct info{
    int x,y,z,h,f;
    int atk,def,mat,mdf,hp,fix;
    string cmd;
    bool flag;
}a[maxn];//存储每一架飞机的信息
inline int read(){
    int x=0;bool f=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=!f;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return f?-x:x;
}//读优
inline void write(int x){
    if(x<0){
        putchar('-');
        write(-x);
    }else{
        if(x/10) write(x/10);
        putchar(x%10+'0');
    }
}//输优
inline void move(){
    for(int i=1;i<=n;++i){
        if(!a[i].flag) continue;//注意:已经坠毁的飞机就不用移动了。
        a[i].x+=movebz[a[i].h][a[i].f].dx;
        a[i].y+=movebz[a[i].h][a[i].f].dy;
        a[i].z+=movebz[a[i].h][a[i].f].dz;
    }
}//向正前方移动
void work(){//打表,存储f、h对应的正前方
    for(int i=0;i<=7;++i){
        movebz[0][i].dx=0;movebz[0][i].dy=0;movebz[0][i].dz=-1;
        movebz[4][i].dx=0;movebz[4][i].dy=0;movebz[4][i].dz=1;
    }
    movebz[1][0].dx=1;movebz[1][0].dy=0;movebz[1][0].dz=-1;
    movebz[1][1].dx=1;movebz[1][1].dy=1;movebz[1][1].dz=-1;
    movebz[1][2].dx=0;movebz[1][2].dy=1;movebz[1][2].dz=-1;
    movebz[1][3].dx=-1;movebz[1][3].dy=1;movebz[1][3].dz=-1;
    movebz[1][4].dx=-1;movebz[1][4].dy=0;movebz[1][4].dz=-1;
    movebz[1][5].dx=-1;movebz[1][5].dy=-1;movebz[1][5].dz=-1;
    movebz[1][6].dx=0;movebz[1][6].dy=-1;movebz[1][6].dz=-1;
    movebz[1][7].dx=1;movebz[1][7].dy=-1;movebz[1][7].dz=-1;

    movebz[3][0].dx=1;movebz[3][0].dy=0;movebz[3][0].dz=1;
    movebz[3][1].dx=1;movebz[3][1].dy=1;movebz[3][1].dz=1;
    movebz[3][2].dx=0;movebz[3][2].dy=1;movebz[3][2].dz=1;
    movebz[3][3].dx=-1;movebz[3][3].dy=1;movebz[3][3].dz=1;
    movebz[3][4].dx=-1;movebz[3][4].dy=0;movebz[3][4].dz=1;
    movebz[3][5].dx=-1;movebz[3][5].dy=-1;movebz[3][5].dz=1;
    movebz[3][6].dx=0;movebz[3][6].dy=-1;movebz[3][6].dz=1;
    movebz[3][7].dx=1;movebz[3][7].dy=-1;movebz[3][7].dz=1;

    movebz[2][0].dx=1;movebz[2][0].dy=0;movebz[2][0].dz=0;
    movebz[2][1].dx=1;movebz[2][1].dy=1;movebz[2][1].dz=0;
    movebz[2][2].dx=0;movebz[2][2].dy=1;movebz[2][2].dz=0;
    movebz[2][3].dx=-1;movebz[2][3].dy=1;movebz[2][3].dz=0;
    movebz[2][4].dx=-1;movebz[2][4].dy=0;movebz[2][4].dz=0;
    movebz[2][5].dx=-1;movebz[2][5].dy=-1;movebz[2][5].dz=0;
    movebz[2][6].dx=0;movebz[2][6].dy=-1;movebz[2][6].dz=0;
    movebz[2][7].dx=1;movebz[2][7].dy=-1;movebz[2][7].dz=0;
}

int main(){
    work();//预处理movebz数组
    n=read(),t=read();
    string s;
    for(register int i=1;i<=n;++i){
        a[i].x=read(),a[i].y=read();
        a[i].z=read(),a[i].h=read();
        a[i].f=read(),a[i].atk=read();
        a[i].def=read(),a[i].mat=read();
        a[i].mdf=read(),a[i].hp=read();
        a[i].fix=read(),a[i].flag=1;
        cin>>a[i].cmd;
    }//读入好多好恶心~
    for(int i=0;i<t;++i){
        move();//每一次都要移动注意题目中的`先`
        for(int j=1;j<=n;++j){
            if(!a[j].flag||a[j].cmd[i]=='n') continue;//如果已经坠毁或这次无操作就continue
            if(a[j].cmd[i]=='u'&&a[j].h<4) a[j].h++;//向上
            if(a[j].cmd[i]=='d'&&a[j].h>0) a[j].h--;//向下
            if(a[j].cmd[i]=='l'){//向左
                if(a[j].f<7) a[j].f++;
                else a[j].f=0;//认真读题,当f为7时如果在向左就会变为0
            }
            if(a[j].cmd[i]=='r'){
                if(a[j].f>0) a[j].f--;//认真读题
                else a[j].f=7;
            }
            if(a[j].cmd[i]=='f') a[j].hp+=a[j].fix;//修理
            if(a[j].cmd[i]=='a'){//子弹
                int sum=0;//判断向前移动了几次。
                bool f=0;//判断有没有打到一架飞机
                int xx=a[j].x,yy=a[j].y,zz=a[j].z;
                there: xx+=movebz[a[j].h][a[j].f].dx;//每次向前移动
                yy+=movebz[a[j].h][a[j].f].dy;
                zz+=movebz[a[j].h][a[j].f].dz;
                sum++;//移动次数加一
                for(int k=1;k<=n;++k){
                    if(!a[k].flag) continue;//如果当前这架飞机坠毁了,就continue
                    if(a[k].x==xx&&a[k].y==yy&&a[k].z==zz){//如果当前到达了一架没有坠毁的飞机
                        f=1//打到了,qwq;
                        int sh=a[j].atk-a[k].def;//计算伤害
                        if(sh>0){//抠除血量
                            a[k].hp-=sh;
                            if(a[k].hp<0){//因为坠毁的飞机最后输出时血量为0直接改成0
                                a[k].hp=0;
                                a[k].flag=0;//它坠毁了
                            }
                        }
                        break;//跳出循坏
                    }
                    if(sum>=8) f=1;//如果进行了8次以上的操作就直接跳出(这是卡测试数据,当时是ioi赛制的比赛)
                }
                if(!f) goto there;//如果还没有打到就再移动
            }
            if(a[j].cmd[i]=='m'){//激光和子弹类似qwq
                int sum=0;//同上
                int xx=a[j].x,yy=a[j].y,zz=a[j].z;
                there2: xx+=movebz[a[j].h][a[j].f].dx;//同上
                yy+=movebz[a[j].h][a[j].f].dy;
                zz+=movebz[a[j].h][a[j].f].dz;
                sum++;//同上
                for(register int k=1;k<=n;++k){
                    if(!a[k].flag) continue;//同上
                    if(a[k].x==xx&&a[k].y==yy&&a[k].z==zz){
                        int sh=a[j].mat-a[k].mdf;//同上
                        if(sh>0){//同上
                            a[k].hp-=sh;
                            if(a[k].hp<=0){
                                a[k].flag=0;
                                a[k].hp=0;
                            }
                        }
                    }
                    if(sum>=8) break;//因为激光是打一行所以不管打没打到继续
                }
                if(sum<8) goto there2;
            }
        }
    }
    for(register int i=1;i<=n;++i){//输出答案qwq
        write(a[i].x);printf(" ");
        write(a[i].y);printf(" ");
        write(a[i].z);printf(" ");
        write(a[i].hp);
        puts("");
    }
    return 0;
}