1 条题解
-
0
自动搬运
来自洛谷,原作者为

向晚大魔王
-搬运于
2025-08-24 22:47:51,当前版本为作者最后更新于2023-06-15 22:40:49,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
小 E 说要有题解,于是就有了题解。
按照题意模拟即可。
代码中始终让 代表当前行动的一方。
一些需要注意的细节:
- 死人之后被动增益需要重算。
- 不造成伤害的攻击也要输出。
- 不造成生命值增加的回复不能输出。
- 被动回血在回合开始时发动。
- 被动扣血在回合结束时发动。
- 注意浮点数精度。
和考场代码编辑距离不超过 20。
大样例不判主动技能回血时是否形成了实际的数值提升也能过,警钟敲烂。
#include <bits/stdc++.h> #define int long long #define double long double int read() { int x=0,f=1,c=getchar(); while(c<48||c>57){if(c=='-')f=-1;c=getchar();} while(c>47&&c<58)x=x*10+c-48,c=getchar(); return x*f; } using namespace std; struct node { char type[23]; int lv,maxhp; int hp; double atk,def; int slv,pslv; char wtype[23]; double watk; double ex_skill=1; double cut; int remainround; void in() { scanf("%s Lv=%lld maxhp=%lld atk=%Lf def=%Lf skillLv=%lld passivesklLv=%lld %s weaponatk=%Lf", type,&lv,&maxhp,&atk,&def,&slv,&pslv,wtype,&watk); // printf("%s %lld %lld %Lf %Lf %lld %lld %s %Lf\n",type,lv,maxhp,atk,def,slv,pslv,wtype,watk); hp=maxhp; } }a[13],b[13]; const int p[]={0,5,3,1,2,4,6,0}; const int ip[]={0,3,4,2,5,1,6,0}; int n=read(),m=read(); double ex_type(node x,node y) { char A=x.type[0],B=y.type[0]; int va=0,vb=0; if(A=='A') va=1; if(A=='S') va=2; if(B=='A') vb=1; if(B=='S') vb=2; int s=(va+3-vb)%3; if(s==0) return 1; else if(s==2) return 0.9; else return 1.1; } double ex_pos(int ap,int dp) { int g=(ap+6-dp)%6; if(g==0) return 1.25; else if(g==1||g==5) return 1; else if(g==2||g==4) return 0.75; else return 0; } const double ew_table[]={0,0.013,0.016,0.019,0.022,0.025}; const double ea_table[]={0,0.01,0.02,0.03,0.04,0.05}; const double es_table[]={0,0.01,0.02,0.03,0.04,0.05}; const double sw_table[]={0,0.1,0.12,0.15,0.17,0.2}; const double sa_table[]={0,0.06,0.07,0.08,0.09,0.1}; const double ss_table[]={0,2.1,2.17,2.24,2.32,2.4}; double Aexatk=1,Aexdef=1,Bexatk=1,Bexdef=1; double heal; void recalc() { heal=0; Aexatk=Aexdef=Bexatk=Bexdef=1; for(int i=1; i<=n; ++i) if(a[i].hp>0) { if(a[i].type[0]=='W') heal+=ew_table[a[i].pslv]; else if(a[i].type[0]=='A') Aexdef+=ea_table[a[i].pslv]; else Aexatk+=es_table[a[i].pslv]; } for(int i=1; i<=m; ++i) if(b[i].hp>0) { if(b[i].type[0]=='W'); else if(b[i].type[0]=='A') Bexdef+=ea_table[b[i].pslv]; else Bexatk+=es_table[b[i].pslv]; } heal=min(heal,0.05L),Aexatk=min(Aexatk,1.1L),Aexdef=min(Aexdef,1.1L); Bexatk=min(Bexatk,1.1L),Bexdef=min(Bexdef,1.1L); } const double eps=1e-9; signed main() { for(int i=1; i<=n; ++i) a[i].in(); for(int i=1; i<=m; ++i) b[i].in(); int lsta=0,lstb=0; int T=read(); char player[]="South"; char rival[]="North"; for(int I=1; I<=T; ++I) { recalc(); // cout<<heal<<endl; for(int i=1; i<=n; ++i) if(a[i].hp>0&&a[i].hp<a[i].maxhp) { int qwq=a[i].maxhp*heal+eps; a[i].hp=min(a[i].maxhp,a[i].hp+qwq); if(qwq) printf("%s %lld recovered +%lld hp -> %lld/%lld\n",player,i,qwq,a[i].hp,a[i].maxhp); } char str[103]; scanf("%s",str); int tgt,ap,dp,cur=-1; for(int i=lsta+1; i<=n; ++i) if(a[i].hp>0){cur=i;break;} if(cur==-1)for(int i=1; i<=n; ++i) if(a[i].hp>0){cur=i;break;} lsta=cur; // for(int i:{5,3,1,2,4,6}) if((i<=m)&&b[i].hp>0) printf("%lld ",i); // puts(""); if(str[1]=='a') //basic { scanf(" target=%lld atkpos=%lld ddgpos=%lld\n",&tgt,&ap,&dp); int dmg=a[cur].atk*a[cur].watk*Aexatk*ex_type(a[cur],b[tgt])*ex_pos(ap,dp) *a[cur].ex_skill/b[tgt].def/Bexdef+eps; b[tgt].hp=max(0ll,b[tgt].hp-dmg); printf("%s %lld took %lld damage from %s %lld -> %lld/%lld\n", rival,tgt,dmg,player,cur,b[tgt].hp,b[tgt].maxhp); a[cur].ex_skill=1; } else if(str[1]=='p') //special { scanf(" target=%lld atkpos=%lld ddgpos=%lld\n",&tgt,&ap,&dp); // double dmg= if(a[cur].wtype[0]=='B') { int dmg=a[cur].atk*a[cur].watk*Aexatk*ex_type(a[cur],b[tgt])*ex_pos(ap,dp) *a[cur].ex_skill/b[tgt].def/Bexdef*1.25+eps; b[tgt].hp=max(0ll,b[tgt].hp-dmg); printf("%s %lld took %lld damage from %s %lld -> %lld/%lld\n", rival,tgt,dmg,player,cur,b[tgt].hp,b[tgt].maxhp); } else if(a[cur].wtype[0]=='G') { int left=ip[tgt]-1,right=ip[tgt]+1; while(left>=1&&(p[left]>m||b[p[left]].hp<=0)) --left; while(right<=6&&(p[right]>m||b[p[right]].hp<=0)) ++right; if(right>6) right=0; left=p[left],right=p[right]; // printf("%d %d\n",left,right); int z=(left>0)+(right>0)+1; int dmg=a[cur].atk*a[cur].watk *Aexatk*ex_type(a[cur],b[tgt])*ex_pos(ap,dp) *a[cur].ex_skill*1.35 /b[tgt].def/Bexdef/z+eps; b[tgt].hp=max(0ll,b[tgt].hp-dmg); printf("%s %lld took %lld damage from %s %lld -> %lld/%lld\n", rival,tgt,dmg,player,cur,b[tgt].hp,b[tgt].maxhp); tgt=left; if(tgt) { recalc(); int dmg=a[cur].atk*a[cur].watk*Aexatk*ex_type(a[cur],b[tgt])*ex_pos(ap,dp) *a[cur].ex_skill*1.35/b[tgt].def/Bexdef/z+eps; b[tgt].hp=max(0ll,b[tgt].hp-dmg); printf("%s %lld took %lld damage from %s %lld -> %lld/%lld\n", rival,tgt,dmg,player,cur,b[tgt].hp,b[tgt].maxhp); } tgt=right; if(tgt) { recalc(); int dmg=a[cur].atk*a[cur].watk*Aexatk*ex_type(a[cur],b[tgt])*ex_pos(ap,dp) *a[cur].ex_skill*1.35/b[tgt].def/Bexdef/z+eps; b[tgt].hp=max(0ll,b[tgt].hp-dmg); printf("%s %lld took %lld damage from %s %lld -> %lld/%lld\n", rival,tgt,dmg,player,cur,b[tgt].hp,b[tgt].maxhp); } } else { int left=ip[tgt]-1,right=ip[tgt]+1; while(left>=1&&(p[left]>m||b[p[left]].hp<=0)) --left; while(right<=6&&(p[right]>m||b[p[right]].hp<=0)) ++right; if(right>6) right=0; left=p[left],right=p[right]; int dmg=a[cur].atk*a[cur].watk*Aexatk*ex_type(a[cur],b[tgt])*ex_pos(ap,dp) *a[cur].ex_skill*1.15/b[tgt].def/Bexdef+eps; b[tgt].hp=max(0ll,b[tgt].hp-dmg); printf("%s %lld took %lld damage from %s %lld -> %lld/%lld\n", rival,tgt,dmg,player,cur,b[tgt].hp,b[tgt].maxhp); tgt=left; if(tgt) { recalc(); int dmg=a[cur].atk*a[cur].watk*Aexatk*ex_type(a[cur],b[tgt])*ex_pos(ap,dp) *a[cur].ex_skill*0.23/b[tgt].def/Bexdef+eps; b[tgt].hp=max(0ll,b[tgt].hp-dmg); printf("%s %lld took %lld damage from %s %lld -> %lld/%lld\n", rival,tgt,dmg,player,cur,b[tgt].hp,b[tgt].maxhp); } tgt=right; if(tgt) { recalc(); int dmg=a[cur].atk*a[cur].watk*Aexatk*ex_type(a[cur],b[tgt])*ex_pos(ap,dp) *a[cur].ex_skill*0.23/b[tgt].def/Bexdef+eps; b[tgt].hp=max(0ll,b[tgt].hp-dmg); printf("%s %lld took %lld damage from %s %lld -> %lld/%lld\n", rival,tgt,dmg,player,cur,b[tgt].hp,b[tgt].maxhp); } } a[cur].ex_skill=1; } else //skill { scanf(" target=%lld\n",&tgt); if(a[cur].slv!=0){ if(a[cur].type[0]=='W') { printf("%s %lld applied %s skill to %s %lld\n",player,cur,a[cur].type,player,tgt); int qwq=a[tgt].maxhp*sw_table[a[cur].slv]+eps; bool ok=(a[tgt].hp==a[tgt].maxhp); a[tgt].hp=min(a[tgt].maxhp,a[tgt].hp+qwq); if(qwq&&ok==0) printf("%s %lld recovered +%lld hp -> %lld/%lld\n",player,tgt,qwq,a[tgt].hp,a[tgt].maxhp); } else if(a[cur].type[0]=='A') { printf("%s %lld applied %s skill to %s %lld\n",player,cur,a[cur].type,rival,tgt); b[tgt].cut=sa_table[a[cur].slv]; b[tgt].remainround=3; } else { printf("%s %lld applied %s skill to %s %lld\n",player,cur,a[cur].type,player,tgt); a[tgt].ex_skill=ss_table[a[cur].slv]; }} } for(int i=1; i<=m; ++i) { if(b[i].remainround>0&&b[i].hp>0) { int qwq=b[i].cut*b[i].maxhp+eps; --b[i].remainround, b[i].hp=max(b[i].hp-qwq,0ll); printf("%s %lld took %lld damage from skill -> %lld/%lld\n",rival,i,qwq,b[i].hp,b[i].maxhp); } } if(rival[0]=='S') { printf("North: "); for(int i:{5,3,1,2,4,6}) if(i<=n) printf("%lld/%lld ",a[i].hp,a[i].maxhp); puts("");printf("South: "); for(int i:{5,3,1,2,4,6}) if(i<=m) printf("%lld/%lld ",b[i].hp,b[i].maxhp); } else { printf("North: "); for(int i:{5,3,1,2,4,6}) if(i<=m) printf("%lld/%lld ",b[i].hp,b[i].maxhp); puts("");printf("South: "); for(int i:{5,3,1,2,4,6}) if(i<=n) printf("%lld/%lld ",a[i].hp,a[i].maxhp); } puts("");puts(""); swap(a,b),swap(lsta,lstb),swap(n,m); swap(rival,player); } bool win=1; for(int i=1; i<=n; ++i) win&=(a[i].hp==0); if(win) printf("Team %s won.",rival); return 0; }
- 1
信息
- ID
- 8812
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者