题解 P5506 【封锁】
//稍作改动 再次提交 望管理大大通过
此文核心收到一位大佬(不知名)启发,因不知为何人,在此感谢
刚看到这道题真的是感觉非常热血沸腾无助!
太弱了看不懂...
后来看了下后面题发现都不会做,就又来看这道题了
其实这道题是一道非常好的模拟????
幸好良心(变态)出题人给了一张表格
因为表里数据比较多,边做边处理太麻烦所以可以先预处理(存数组里)
int s[5][8][3]=
{
{
{0,0,-1},{0,0,-1},{0,0,-1},{0,0,-1},{0,0,-1},{0,0,-1},{0,0,-1},{0,0,-1}
},
{
{1,0,-1},{1,1,-1},{0,1,-1},{-1,1,-1},{-1,0,-1},{-1,-1,-1},{0,-1,-1},{1,-1,-1}
},
{
{1,0,0},{1,1,0},{0,1,0},{-1,1,0},{-1,0,0},{-1,-1,0},{0,-1,0},{1,-1,0}
},
{
{1,0,1},{1,1,1},{0,1,1},{-1,1,1},{-1,0,1},{-1,-1,1},{0,-1,1},{1,-1,1}
},
{
{0,0,1},{0,0,1},{0,0,1},{0,0,1},{0,0,1},{0,0,1},{0,0,1},{0,0,1}
}
};
其中第一维是h,第二维是f,第三维就是x,y,z(方位) 这样便于处理正方向
x+=s[h][f][0];
y+=s[h][f][1];
z+=s[h][f][2];
f:当前水平朝向(范围0-7) h:竖直朝向(范围0-4) (如果f,h对应的是什么都不知道的话,你可以去P1000大佬区了)
题中代码中用到 goto 像我一样的蒟蒻看这里 感谢博主
如有不明白可自行百度
话不多说 上代码
#include<bits/stdc++.h>
using namespace std;
int a[205][15];//大佬们用的都是结构体,用结构体确实会方便不少
int vis[105][105][105];
char ch[205][205];
int s[5][8][3]=
{
{
{0,0,-1},{0,0,-1},{0,0,-1},{0,0,-1},{0,0,-1},{0,0,-1},{0,0,-1},{0,0,-1}
},
{
{1,0,-1},{1,1,-1},{0,1,-1},{-1,1,-1},{-1,0,-1},{-1,-1,-1},{0,-1,-1},{1,-1,-1}
},
{
{1,0,0},{1,1,0},{0,1,0},{-1,1,0},{-1,0,0},{-1,-1,0},{0,-1,0},{1,-1,0}
},
{
{1,0,1},{1,1,1},{0,1,1},{-1,1,1},{-1,0,1},{-1,-1,1},{0,-1,1},{1,-1,1}
},
{
{0,0,1},{0,0,1},{0,0,1},{0,0,1},{0,0,1},{0,0,1},{0,0,1},{0,0,1}
}
};
int main(){
int n,t;
cin>>n>>t;
for(int i=1;i<=n;i++){
for(int j=1;j<=11;j++)
cin>>a[i][j];
cin>>ch[i];
a[i][12]=1;
//a[i][1~11]分别对应题中的各个参量
//a[i][12] 表示这架飞机是否死亡 1为活着 0为死亡
}
for(int k=0;k<t;k++){
for(int i=1;i<=n;i++)
{
a[i][1]+=s[a[i][4]][a[i][5]][0];
a[i][2]+=s[a[i][4]][a[i][5]][1];
a[i][3]+=s[a[i][4]][a[i][5]][2];
}
for(int i=1;i<=n;i++)//4 h 5 f
{
if(!a[i][12]||ch[i][k]=='N') continue;//如果已经坠毁或这次无操作就continue
else if(ch[i][k]=='F'){//回血
a[i][10]+=a[i][11];
}
else if(ch[i][k]=='L'){//若为上限则重载(循环 0,1,2,3,4,5,6,7,0,1 ……)
if(a[i][5]==7)
a[i][5]=0;
else
a[i][5]++;
}
else if(ch[i][k]=='R'){//同上
if(a[i][5]==0)
a[i][5]=7;
else
a[i][5]--;
}
else if(ch[i][k]=='U'){//U/D 与L/R 不同 ,超过范围就为无效操作
if(a[i][4]<4)
a[i][4]++;
}
else if(ch[i][k]=='D'){//同上
if(a[i][4]>0)
a[i][4]--;
}
else if(ch[i][k]=='M'){
int sum=0;//判断向前移动了几次。
int xx=a[i][1],yy=a[i][2],zz=a[i][3];//记录当前飞机方位
there2: xx+=s[a[i][4]][a[i][5]][0];//以下模拟移动
yy+=s[a[i][4]][a[i][5]][1];
zz+=s[a[i][4]][a[i][5]][2];
sum++;//移动次数加1
for(register int k=1;k<=n;++k){
if(!a[k][12]) continue;//如果飞机死亡
if(a[k][1]==xx&&a[k][2]==yy&&a[k][3]==zz){
int sh=a[i][8]-a[k][9];
if(sh>0){//如果差值为正数才有伤害
a[k][10]-=sh;
if(a[k][10]<=0){
a[k][12]=0;
a[k][11]=0;
}
}
}
if(sum>=100) break;//继续
}
if(sum<100) goto there2;//回到there2处(个人理解为变异的while循环)
}
else if(ch[i][k]=='A'){//子弹
int sum=0;
bool f=0;//判断有没有打到一架飞机
int xx=a[i][1],yy=a[i][2],zz=a[i][3];
there: xx+=s[a[i][4]][a[i][5]][0];//同上
yy+=s[a[i][4]][a[i][5]][1];
zz+=s[a[i][4]][a[i][5]][2];
sum++;//移动次数加一
for(int k=1;k<=n;++k){
if(!a[k][12]) continue;//如果当前这架飞机坠毁了,就continue
if(a[k][1]==xx&&a[k][2]==yy&&a[k][3]==zz){//如果当前到达了一架没有坠毁的飞机
f=1;//打到了,qwq;
int sh=a[i][6]-a[k][7];//计算伤害
if(sh>0){//扣除血量
a[k][10]-=sh;
if(a[k][10]<0){//因为坠毁的飞机最后输出时血量为0直接改成0
a[k][10]=0;
a[k][12]=0;//坠毁
}
}
break;//跳出循坏
}
if(sum>=100) f=1;//如果进行了100次以上的操作就直接跳出,卡数据
}
if(!f) goto there;//如果还没有打到就再移动
}
}
}
for(int i=1;i<=n;i++){
cout<<a[i][1]<<" "<<a[i][2]<<" "<<a[i][3]<<" "<<a[i][10]<<endl;
}
return 0;
}
码风粗陋,多多包涵