当前位置:   article > 正文

第十三届蓝桥杯省赛大学B组编程题(c++)

第十三届蓝桥杯省赛大学B组编程题(c++)

D.刷题统计

二分(AC):

注意:二分时右边界 right 的确定

  1. #include<iostream>
  2. using namespace std;
  3. long long a,b,n;
  4. bool check(long long x){
  5. long long t=x/7;
  6. x%=7;
  7. long long temp=0;
  8. if(x<=5) temp=x*a;
  9. else temp=5*a+(x-5)*b;
  10. long long cnt=t*(5*a+2*b)+temp;
  11. return cnt>=n;
  12. }
  13. int main(){
  14. cin>>a>>b>>n;
  15. long long left=0,right=n/min(a,b)+1;
  16. while(left<right){
  17. long long mid=(left+right)/2;
  18. if(check(mid)) right=mid;
  19. else left=mid+1;
  20. }
  21. cout<<left<<endl;
  22. return 0;
  23. }

E.修剪灌木

数学思维(AC):

  1. #include<iostream>
  2. using namespace std;
  3. int n;
  4. int main(){
  5. cin>>n;
  6. for(int i=1;i<=n;i++){
  7. int left=2*(i-1);
  8. int right=2*(n-i);
  9. cout<<max(left,right)<<endl;
  10. }
  11. return 0;
  12. }

F.X 进制减法

暴力+模拟(AC):

十年OI一场空,不开浪浪见祖宗

  1. #include<iostream>
  2. using namespace std;
  3. typedef long long ll;
  4. const int N=1e5+5;
  5. const ll mod=1e9+7;
  6. ll n,ma,mb,ans1,ans2,a[N],b[N],x[N],v[N];
  7. int main(){
  8. ios::sync_with_stdio(false),cin.tie(0);
  9. cin>>n>>ma;
  10. for(int i=ma-1;i>=0;i--) cin>>a[i];
  11. cin>>mb;
  12. for(int i=mb-1;i>=0;i--) cin>>b[i];
  13. for(int i=max(ma-1,mb-1);i>=0;i--) x[i]=max((long long)2,max(a[i]+1,b[i]+1));
  14. for(int i=0;i<=max(ma,mb)-1;i++){
  15. if(i==0) v[i]=1;
  16. else{
  17. v[i]=v[i-1]*x[i-1];
  18. v[i]%=mod;
  19. }
  20. }
  21. for(int i=ma-1;i>=0;i--) ans1+=v[i]*a[i],ans1%=mod;
  22. for(int i=mb-1;i>=0;i--) ans2+=v[i]*b[i],ans2%=mod;
  23. cout<<(ans1-ans2+mod)%mod<<endl;
  24. return 0;
  25. }

G.统计子矩阵

二维前缀和+暴力(70 points):

  1. #include<iostream>
  2. using namespace std;
  3. const int N=505;
  4. int n,m,k,a[N][N];
  5. long long ans;
  6. int main(){
  7. cin>>n>>m>>k;
  8. for(int i=1;i<=n;i++) {
  9. for(int j=1;j<=m;j++) {
  10. cin>>a[i][j];
  11. a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
  12. }
  13. }
  14. for(int i=1;i<=n;i++){
  15. for(int j=1;j<=m;j++){
  16. for(int x=1;x<=i;x++){
  17. for(int y=1;y<=j;y++){
  18. if(k>=(a[i][j]+a[x-1][y-1]-a[x-1][j]-a[i][y-1])){
  19. ans++;
  20. }
  21. }
  22. }
  23. }
  24. }
  25. cout<<ans<<endl;
  26. return 0;
  27. }

优化(AC):

  1. #include<iostream>
  2. using namespace std;
  3. const int N=505;
  4. int n,m,k,a[N][N];
  5. long long ans;
  6. int main(){
  7. cin>>n>>m>>k;
  8. for(int i=1;i<=n;i++) {
  9. for(int j=1;j<=m;j++) {
  10. cin>>a[i][j];
  11. a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
  12. }
  13. }
  14. for(int i=1;i<=n;i++){
  15. for(int j=i;j<=n;j++){
  16. for(int l=1,r=1;r<=m;r++){
  17. while(l<=r&&k<(a[j][r]+a[i-1][l-1]-a[j][l-1]-a[i-1][r])){
  18. l++;
  19. }
  20. ans+=r-l+1;
  21. }
  22. }
  23. }
  24. cout<<ans<<endl;
  25. return 0;
  26. }

这题暴力70足以...... 

H.积木画

递推与递归(AC):

  1. #include<iostream>
  2. using namespace std;
  3. const long long mod=1e9+7;
  4. const int N=1e7+5;
  5. int n,f[N];
  6. int main(){
  7. cin>>n;
  8. f[1]=1,f[2]=2,f[3]=5;
  9. if(n>=4){
  10. for(int i=4;i<=n;i++){
  11. f[i]=2*f[i-1]%mod+f[i-3]%mod;
  12. f[i]%=mod;
  13. }
  14. }
  15. cout<<f[n]<<endl;
  16. return 0;
  17. }

思路和洛谷题单算法1-4递推与递归 P1990 覆盖墙壁 一模一样......

I.李白打酒加强版

动态规划+记忆化搜索(AC):

  1. #include<iostream>
  2. #include<cstring>
  3. using namespace std;
  4. const int N=105;
  5. const int mod=1e9+7;
  6. int n,m,dp[N][N][N];//当前酒量,剩余遇见店的次数,剩余遇见花的次数
  7. int dfs(int x,int y,int z) {
  8. //出现负数不合法
  9. if(x<0||y<0||z<0) return 0;
  10. //当前酒量不可能大于剩余遇见花的次数"
  11. if(x>z) return 0;
  12. //最后一次必须遇见花并且酒量只剩1
  13. if(z==1) return y==0&&x==1;
  14. //记忆化
  15. if(dp[x][y][z]!=-1) return dp[x][y][z];
  16. //逢店加倍,遇花减一
  17. dp[x][y][z]=(dfs(x*2,y-1,z)+dfs(x-1,y,z-1))%mod;
  18. return dp[x][y][z];
  19. }
  20. int main(){
  21. memset(dp,-1,sizeof(dp));
  22. cin>>n>>m;
  23. cout<<dfs(2,n,m)<<endl;
  24. return 0;
  25. }

J.砍竹子

  1. unorder_set特点:无序不重复的集合
  2. //头文件:
  3. #include<unordered_set>
  4. //常用函数:
  5. unorder_set.empty(); //判断容器是否为空,空为true,反之为false
  6. unorder_set.size();   //返回容器大小
  7. unorder_set.begin();  //返回迭代器开始
  8. unorder_set.end();    //返回迭代器结束
  9. unorder_set.find(x);  //返回x在迭代器的位置
  10. unorder_set.count(x); //返回x在容器的个数
  11. unorder_set.insert(x);//将x插入到容器中
  12. unorder_set.erase(x); //删除x,成功返回1,反之返回0
  13. unorder_set.clear();  //清空容器

解释样例:

  1. #include<iostream>
  2. #include<unordered_set>
  3. #include<cmath>
  4. typedef long long ll;
  5. using namespace std;
  6. ll ans; //累计不同的数的个数
  7. unordered_set<ll>s;//保存上次出现过的数
  8. int main() {
  9. int n;
  10. cin>>n;
  11. for(int i=1;i<=n;i++) {
  12. ll temp;
  13. cin>>temp;
  14. unordered_set<ll>cur; //每次读取一个数时,用来记录当前数的所有中间结果
  15. while(temp!=1) {
  16. cur.insert(temp); //将当前数加入当前集合
  17. if (s.find(temp)==s.end()) ans++;//如果当前数不在之前的集合内,ans自增
  18. temp = sqrtl(temp/2+1); //计算下一个数
  19. }
  20. s=cur; //更新保存所有出现过的数的集合
  21. }
  22. cout<<ans<<endl;
  23. return 0;
  24. }

这题真难想...... 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/424686
推荐阅读
相关标签
  

闽ICP备14008679号