题目背景
出假题的lGJ又被机智的同学同学们打败了,
于是LGJ使用分神术复制了n个LGJ并且有的LGJ
有些LGJ带上了路障,也有带上了铁帽,还有的带上了撑杆。
你召唤了mi_ruo来保护自己的大本营。
数据较原先有加强(并不大,只是hack掉了跳两次可过的情况)
题目描述
mi_ruo可以分身成m个mi_ruo,LGJ距离你的大本营的距离为k。
每个已经出现的LGJ向前走一次,如果LGJ走的格有mi_ruo,则mi_ruo会被带走(带走不耗时间)每回合每个mi_ruo发动一次可爱攻击。(LGJ先走,mi_ruo再发动可爱攻击,并且mi_ruo只能打最前方的LGJ,即本回合最前的LGJ
gg了也不会对后面的LGJ造成伤害)
从第一格向后依次为一个mi_ruo(开局所有mi_ruo已准备好)。
如果LGJ没有出完每3回合出一次LGJ
以下为不同种类的LGJ的血量与速度
血量 速度(次/格)
普通 5 1
路障 10 1
铁桶 20 1
撑杆 10 2 遇到第一个mi_ruo跳过速度变为1
以下为题意补充 :
About mi_ruo: 为”向LGJ“mi_ruo,即如果一只LGJ出现在她后面(并且此时她还没被LGJ带走),她会对LGJ造成伤害,所有mi_ruo都只会对第一个LGJ造成伤害
About LGJ:撑杆LGJ在出现时并不会出现在第K个格子里,它会直接出现在第K−1个格子里,也就是从第K+1个格子里走了两格。
撑杆跳过mi_ruo的时候,如果前面两格(他在这一回合所能达到的地方)任意一格有mi_ruo,他会直接跳到第一个mi_ruo后边并把这个格子内的mi_ruo带走,被跳过的mi_ruo依旧存活
数据保证不会出现在同一个格子里出现两个LGJ的情况
输入格式
输入:n,m,k保证(m<k) 接下来n行输入LGJ的属性,1为普通,2为路障,3为铁桶,4为撑杆.
输出格式
输出:如果能击败所有LGJ第一行输出"water GJ you are so vegetable!"(引号不输出)第二行输出LGJ最多走到第几格。
(LGJ从第k格向第一格走,可以理解为从第k+1格开始走)
如果LGJ可以进入大本营第一行输出"cimao GJ wins...!what fuck"
第二行输出第几个LGJ首先进入大本营。
输入输出样例
2 2 10 1 1
water GJ you are so vegetable! 8
说明/提示
全部输入数据均小于50
实际最大点才30
关于问题:
在原Oj里面并没有注明同一格中不会同时出现两个LGJ,所以本篇代码是按会出现去写的。
首先是变量的定义:
struct zombie{ int hp,sp;//hp为当前僵尸的血量,sp为当前僵尸能移动的格数 bool jp;//jp为当前僵尸能否跳跃 } zb[50];//zb[i]结构体存储第i只僵尸的数据 int m,n,k,type,tt=1,mi=999;//m为草坪长度,n为僵尸数量,k为豌豆数量,type在输入时获取僵尸的类型,tt存储当前出到第几只僵尸了,mi记录僵尸走得最远的格子 int typehp[5]={0,5,10,20,10},typesp[5]={0,1,1,1,2}; //这两个数组用以获取该类型僵尸的数据
之后输入各种数据:
cin>>n>>k>>m; for(int i=1;i<=n;i++) { cin>>type; zb[i].hp=typehp[type]; zb[i].sp=typesp[type]; if(type==4) zb[i].jp=1; }//输入僵尸属性
我们可以建一个数组,去模拟草坪上的状况。
1 int lawn[3][150],k;//k为豌豆数量 2 lawn[0][0]=-2; 3 for(int i=1;i<=k;i++) lawn[0][i]=-1; 4 //建立草坪,-2为家,-1为豌豆 ,lawn[0]存家,豌豆和这一格上的僵尸数 5 //lawn[1]存这一格上的第一只僵尸的编号,lawn[2]存这一格上的第二只僵尸的编号
如果表示出来的话,在实际运行中是这种感觉:
-2 | -1 | 1 | -1 | 0 | 2 | 0 | 0 | 0 | 1 |
0 | 0 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | 4 |
0 | 0 | 0 | 0 | 0 | 3 | 0 | 0 | 0 | 0 |
其中,第一行就是lawn[0],-2表示这一格是家,-1表示这一格上是豌豆,0表示这一格为空,正整数表示这一格上僵尸的数量。
第二,三行存储该格子上僵尸的编号,就是zb[i]中的i。
所以我们可以通过这个获取该僵尸的所有数据。
撒,开始我们的模拟吧~~~
关于模拟的过程,都打在代码的注释里了。
关于僵尸的移动:
for(int round=3;round<=3*n+m+2;round++)//进行模拟 ,3*n+m+2保证所有僵尸都有走到家里的机会 { if(round%3==0&&round<=3*n) lawn[0][m+1]=1,lawn[1][m+1]=tt++; //每三回合出一只僵尸 for(int i=1;i<=m+1;i++)//僵尸先走 { if(lawn[0][i]>0)//若此格上僵尸数大于0 for(int r=1;r<=2;r++)//遍历这一格上所有僵尸 { int p=lawn[r][i];//p为当前僵尸标号 if(p!=0) for(int t=1;t<=zb[p].sp;t++)//僵尸进行移动 { if(i-t<mi)mi=i-t; int nxt=lawn[0][i-t];//nxt为僵尸要移动到的格子 if(nxt==-2) {cout<<"cimao GJ wins...!what fuck"<<endl<<p;return 0;} //若下一格是家,则僵尸胜,终止程序 else if(nxt==-1)//若下一格为豌豆 { if(zb[p].jp==1)//若僵尸能跳 { if(i-t-1<mi)mi=i-t-1; if(lawn[0][i-t-1]==-2) {cout<<"cimao GJ wins...!what fuck"<<endl<<p;return 0;} else { lawn[0][i-t-1]=1;lawn[1][i-t-1]=p; lawn[0][i-t+1]--;lawn[r][i-t+1]=0; zb[p].jp=0;zb[p].sp=1; }//跳过面前的植物 ,改变跳跃状态和速度 } else//若僵尸不能跳 { lawn[0][i-t]=1;lawn[1][i-t]=p; lawn[0][i-t+1]--;lawn[r][i-t+1]=0; }//把豌豆吃了 } else if(nxt==1)//若下一格有僵尸 { lawn[0][i-t]=2;lawn[2][i-t]=p; lawn[0][i-t+1]--;lawn[r][i-t+1]=0; }//存在lawn[2]里 else//若下一格为空 { lawn[0][i-t]=1;lawn[1][i-t]=p; lawn[0][i-t+1]--;lawn[r][i-t+1]=0; } } } }
然后关于豌豆的攻击:
int dmg=0;//初始化伤害 for(int i=1;i<=m;i++)//植物再打 { if(lawn[0][i]==-1) dmg++;//若这格上是豌豆,则累积伤害 } for(int i=1;i<=m;i++)//再从头寻找第一只僵尸 { if(lawn[0][i]>0)//这一格上僵尸数大于0 { int p=lawn[1][i]; zb[p].hp-=dmg; dmg=0; if(zb[p].hp<=0) { lawn[0][i]--; lawn[1][i]=0; } break; }//对其造成伤害,伤害值归零,若僵尸死亡,将其从草坪中清除 } }//如过前面没有一只僵尸到达家里,就输出下面这个~ cout<<"water GJ you are so vegetable!"<<endl<<mi;
很多地方其实都能优化,但这题数据范围实在太水了,没有必要,所以我就懒得改辣~
最后是高清完整版代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 struct zombie{ 4 int hp,sp; 5 bool jp; 6 } zb[50]; 7 int m,n,k,lawn[3][150],type,tt=1,mi=999; 8 int typehp[5]={0,5,10,20,10},typesp[5]={0,1,1,1,2}; 9 int main() 10 { 11 cin>>n>>k>>m; 12 for(int i=1;i<=n;i++) 13 { 14 cin>>type; 15 zb[i].hp=typehp[type]; 16 zb[i].sp=typesp[type]; 17 if(type==4) zb[i].jp=1; 18 }//输入僵尸属性 19 lawn[0][0]=-2; 20 for(int i=1;i<=k;i++) lawn[0][i]=-1; 21 //建立草坪,-2为家,-1为豌豆 ,lawn[0]存家,豌豆和这一格上的僵尸数 22 //lawn[1]存这一格上的第一只僵尸,lawn[2]存这一格上的第二只僵尸 23 for(int round=3;round<=3*n+m+2;round++)//进行模拟 ,3*n+m+2保证所有僵尸都有走到家里的机会 24 { 25 if(round%3==0&&round<=3*n) lawn[0][m+1]=1,lawn[1][m+1]=tt++; 26 //每三回合出一只僵尸 27 for(int i=1;i<=m+1;i++)//僵尸先走 28 { 29 if(lawn[0][i]>0)//若此格上僵尸数大于0 30 for(int r=1;r<=2;r++)//遍历这一格上所有僵尸 31 { 32 int p=lawn[r][i];//p为当前僵尸标号 33 if(p!=0) 34 for(int t=1;t<=zb[p].sp;t++)//僵尸进行移动 35 { 36 if(i-t<mi)mi=i-t; 37 int nxt=lawn[0][i-t];//nxt为僵尸要移动到的格子 38 if(nxt==-2) {cout<<"cimao GJ wins...!what fuck"<<endl<<p;return 0;} 39 //若下一格是家,则僵尸胜,终止程序 40 else if(nxt==-1)//若下一格为豌豆 41 { 42 if(zb[p].jp==1)//若僵尸能跳 43 { 44 if(i-t-1<mi)mi=i-t-1; 45 if(lawn[0][i-t-1]==-2) {cout<<"cimao GJ wins...!what fuck"<<endl<<p;return 0;} 46 else 47 { 48 lawn[0][i-t-1]=1;lawn[1][i-t-1]=p; 49 lawn[0][i-t+1]--;lawn[r][i-t+1]=0; 50 zb[p].jp=0;zb[p].sp=1; 51 }//跳过面前的植物 ,改变跳跃状态和速度 52 } 53 else//若僵尸不能跳 54 { 55 lawn[0][i-t]=1;lawn[1][i-t]=p; 56 lawn[0][i-t+1]--;lawn[r][i-t+1]=0; 57 }//把豌豆吃了 58 } 59 else if(nxt==1)//若下一格有僵尸 60 { 61 lawn[0][i-t]=2;lawn[2][i-t]=p; 62 lawn[0][i-t+1]--;lawn[r][i-t+1]=0; 63 }//存在lawn[2]里 64 else//若下一格为空 65 { 66 lawn[0][i-t]=1;lawn[1][i-t]=p; 67 lawn[0][i-t+1]--;lawn[r][i-t+1]=0; 68 } 69 } 70 } 71 } 72 //----------------------------------调试用,输出草坪状况------------------------------------- 73 /*cout<<"round:"<<round<<endl; 74 for(int i=0;i<=2;i++) 75 { 76 for(int r=0;r<=m+1;r++) 77 { 78 printf("%3d ",lawn[i][r]); 79 } 80 cout<<endl; 81 } 82 cout<<"--------------------------------------------------"<<endl;*/ 83 //----------------------------------调试用,输出草坪状况------------------------------------ 84 int dmg=0;//初始化伤害 85 for(int i=1;i<=m;i++)//植物再打 86 { 87 if(lawn[0][i]==-1) dmg++;//若这格上是豌豆,则累积伤害 88 } 89 for(int i=1;i<=m;i++)//再从头寻找第一只僵尸 90 { 91 if(lawn[0][i]>0)//这一格上僵尸数大于0 92 { 93 int p=lawn[1][i]; 94 zb[p].hp-=dmg; 95 dmg=0; 96 if(zb[p].hp<=0) 97 { 98 lawn[0][i]--; 99 lawn[1][i]=0; 100 } 101 break; 102 }//对其造成伤害,伤害值归零,若僵尸死亡,将其从草坪中清除 103 } 104 }//如过前面没有一只僵尸到达家里,就输出下面这个~ 105 cout<<"water GJ you are so vegetable!"<<endl<<mi; 106 }