• 【题解】洛谷 P5506 封锁


    题目

    P5506 封锁

    思路

    模拟
    (large ext{读题一定要细心})
    解释都在代码里。

    (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>=400) 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>=400) break;//因为激光是打一行所以不管打没打到继续
    				}
    				if(sum<400) 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;
    }
    
  • 相关阅读:
    当期所得税费用总额
    所得税净利润算法
    [AGC028B]Removing Blocks 概率与期望
    bzoj 4319: cerc2008 Suffix reconstruction 贪心
    bzoj 2430: [Poi2003]Chocolate 贪心
    BZOJ 2839: 集合计数 广义容斥
    luogu 5505 [JSOI2011]分特产 广义容斥
    CF504E Misha and LCP on Tree 后缀自动机+树链剖分+倍增
    CF798D Mike and distribution 贪心
    CF707D Persistent Bookcase 可持久化线段树
  • 原文地址:https://www.cnblogs.com/poi-bolg-poi/p/11349847.html
Copyright © 2020-2023  润新知