每天打卡一小时 第十八天 编译四部曲
第一部曲 自然语言
这段代码的问题是要求在第二组士兵出现后是否能用第一组士兵杀死所有第二组士兵。该代码通过深度优先搜索来枚举所有可能的攻击顺序,并使用一个队列记录下每次攻击的具体细节。
首先,代码从输入中获取了两组士兵的数据。第一组士兵有攻击力和生命值,第二组士兵有防御值。第二组士兵的出场顺序是已知的,存储在一个结构体数组中,按照防御值从小到大排列。
接下来,程序使用一个深度优先搜索来枚举所有可能的攻击顺序。搜索的过程中,程序会先判断当前第二组士兵是否已经全部被杀死,如果是,则返回“Defile”并输出每次攻击的细节;否则继续搜索。
在搜索的过程中,程序会尝试让所有第一组士兵中的每一个都攻击当前轮到的第二组士兵,然后递归调用自身。如果在某次递归中第二组士兵已经全部被杀死,则记录下当前攻击顺序的细节,并返回。如果当前攻击顺序无法杀死所有第二组士兵,则回溯到上一层递归,继续尝试其他攻击顺序。
最后根据搜索的结果输出“Twisting Nether”或“Defile”。如果输出了Defile,则程序会从记录的队列中逐一输出每次攻击的细节。
第二部曲 流程图
调用了dsf不会流程图啊
第三部曲 代码
#include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;i++) #define ll long long int n,m; struct TMP{ int k,b; bool operator<(const TMP &R)const{ return k<R.k; } }e[10]; int a[2][10],b[2][10]; bool f[24]; int ans=0; struct node{ int k,b,kk,bb; //k/b -> kk/bb }; deque<node>Q; void dfs(int pos){ if(pos>m){ memset(f,0,sizeof f); int ma=0,ct=0; rep(i,1,n){ if(b[0][i]<=0)continue; if(f[b[0][i]]==0){ f[b[0][i]]=1; ma=max(ma,b[0][i]); ct++; } } rep(i,1,m){ if(b[1][i]<=0)continue; if(f[b[1][i]]==0){ f[b[1][i]]=1; ma=max(ma,b[1][i]); ct++; } } if(ma==ct)ans=1; return ; } //not attack if(a[1][pos]==0){ dfs(pos+1); return ; } dfs(pos+1); if(ans)return; // attack rep(i,1,n){ if(b[0][i]<=0)continue; int x=b[0][i],y=b[1][pos]; Q.push_back((node){a[1][pos],b[1][pos],a[0][i],b[0][i]}); b[0][i]-=a[1][pos]; b[1][pos]-=a[0][i]; dfs(pos+1); if(ans)return; Q.pop_back(); b[0][i]=x; b[1][pos]=y; } } int main(){ int t;scanf("%d",&t); while(t--){ ans=0; scanf("%d",&n); rep(i,1,n) scanf("%d%d",a[0]+i,b[0]+i); scanf("%d",&m); rep(i,1,m) scanf("%d%d",&e[i].k,&e[i].b); sort(e+1,e+1+m); rep(i,1,m) a[1][i]=e[i].k, b[1][i]=e[i].b; dfs(1); if(ans){ printf("Defile\n"); while(!Q.empty()){ node p=Q.front();Q.pop_front(); //printf("%d/%d attack %d/%d\n",p.k,p.b,p.kk,p.bb); } } else printf("Twisting Nether\n"); } }
第四部曲 总结
dsf 真的好用啊