1.小红的字符串大小写变换
直接按照题意模拟就可以,将大小写互转
#include<bits/stdc++.h> using namespace std; int n,k; string s; void change(int i,int w) { if(w==0) { if(s[i]>='a'&&s[i]<='z') s[i]=s[i]-'a'+'A'; } else { if(s[i]>='A'&&s[i]<='Z') s[i]=s[i]-'A'+'a'; } } int main() { cin>>n>>k>>s; for(int i=0;i<n;++i) {if(i<k) change(i,0); else change(i,1); } cout<<s; }2.小红杀怪
数据较小,由于怪物血量小于20,故而每种类型的攻击最多20次,枚举所有可能,选择最小的。
#include<bits/stdc++.h> using namespace std; int a,b,x,y,ans; int main() { cin>>a>>b>>x>>y; ans=INF; for(int i=0;i<=40;++i) for(int j=0;j<=40;++j) //使用x for(int w=0;w<=40;++w) if(a-w*y-i*x<=0&&b-w*y-j*x<=0) ans=min(ans,i+j+w); cout<<ans; }3.小红的元素分裂
动态规划,首先依照题意预处理处所有数字可以被拆分成若干个1的最小次数,随后将题目所给出的所有数字累加即可。
#include<bits/stdc++.h> using namespace std; #define maxx 200000 int n,m,ans; int dp[maxx]; int all[maxx]; int main() { cin>>n; for(int i=1;i<=n;++i) {cin>>all[i]; m=max(m,all[i]); } dp[1]=0; for(int i=2;i<=m;++i) {dp[i]=dp[i-1]+1; for(int j=2;j<=sqrt(i);++j) if(i%j==0) dp[i]=min(dp[i],dp[i/j]+dp[j]+1); } for(int i=1;i<=n;++i) ans=ans+dp[all[i]]; cout<<ans; }注意转移方程,在寻找倍数时,可以采用根号下寻找,也可以采用筛法一次性预处理出所有数字的倍数,后者时间复杂度为O(nlnn),优于前者O(nsqrt(n)),或者采取更好的寻找倍数的算法。
4.小红的扫雷游戏
数据较小,可以搜索,可以依此枚举每个格子是否为雷,然后判断是否合法,可以进行适当的可行性剪枝。
另外注意判断每个格子是否唯一,可以在所有合法情况下记录每个格子的值,如果一个格子在所有合法情况都是雷,那么它一定是雷,如果都不是雷,那么它一定不是雷,剩下的未知。
同时注意在枚举的时候不必枚举已经有数字的区域,复杂度O(n*n*2^n*n),n取4.
另外,如果测试点1和5过不去,有可能是没有考虑扫过雷的区域是0的情况。
#include<bits/stdc++.h> using namespace std; int all[10][10]; int all1[10][10]; int ans[10][10][2]; string s; void solve(int i,int j) { if(i==5&&j==1) { for(int i=1;i<=4;++i) for(int j=1;j<=4;++j) { int noww=0; if(all[i][j]!=-1) { for(int x=-1;x<=1;++x) for(int y=-1;y<=1;++y) noww=noww+all1[i+x][j+y]; if(noww!=all[i][j]) return ; //判断合法性 } } for(int i=1;i<=4;++i) for(int j=1;j<=4;++j) ans[i][j][all1[i][j]]=1; return ; } all1[i][j]=0; if(j<4) solve(i,j+1); else solve(i+1,1); if(all[i][j]==-1) {all1[i][j]=1; if(j<4) solve(i,j+1); else solve(i+1,1); } } int main() { for(int i=1;i<=4;++i) {cin>>s; for(int j=1;j<=4;++j) if(s[j-1]!='.') all[i][j]=s[j-1]-'0'; else all[i][j]=-1; } solve(1,1); for(int i=1;i<=4;++i) for(int j=1;j<=4;++j) { if(all[i][j]!=-1) cout<<all[i][j]; else { if(ans[i][j][0]==1&&ans[i][j][1]==0) cout<<'O'; else if(ans[i][j][0]==0&&ans[i][j][1]==1) cout<<'X'; else cout<<"."; } if(j==4) cout<<"\n"; } }