【做题的小明】Acwing2023夏季每日一题Week4部分(2023.7.16)

Acwing.4118 狗和猫

  • 题意: 给定 N ( 1 e 4 ) N(1e4) N(1e4) 只有吃饭顺序的狗和猫,给定狗粮数量和猫粮数量 D ( 1 e 6 ) D(1e6) D(1e6) 和猫粮数量 C ( 1 e 6 ) C(1e6) C(1e6) ,并且每次投喂狗粮都会增加 M ( 1 e 6 ) M(1e6) M(1e6) 个猫粮,投喂只能按照给定顺序投喂,问狗是否能被全部投喂。
  • 思路:按照题意模拟即可,需要注意的坑点是猫粮要开 l o n g l o n g long long longlong ,做的时候没开看了好久结果是没开 l o n g l o n g longlong longlong 爆了看,一开始还写错了,所以写的时候要慢慢写加看好数据范围。
  • C o d e Code Code
#include <bits/stdc++.h>
using namespace std;

bool solve(){
   long long n,cat,dog,t;
   cin>>n>>dog>>cat>>t;
   string s;
   cin>>s;
   for(int i=0;i<n;i++){
       if(s[i]=='C'){
           if(cat>0)   cat--;
           else{
               for(int j=i+1;j<n;j++)
                   if(s[j]=='D')   return false;
               return true;
           }
       }
       else{
           if(dog>0)   dog--,cat+=t;
           else{
               return false;
           }
       }
   }
   return true;
}

int main(){
   int t;
   cin>>t;
   for(int i=1;i<=t;i++){
       if(solve()) printf("Case #%d: YES\n",i);
       else    printf("Case #%d: NO\n",i);
   }
   return 0;
}

Acwing.3748 递增子串

  • 题意: 给定一个长度为 N ( 2 e 5 ) N(2e5) N(2e5) 字符串,问以每个字符结尾的最长子串长度是多少。
  • 思路: 考虑递推,容易想到可以从左往右做,每一个字符如果比上一个字符大,那么可以从上一个+1来转移,否则重新从1开始。
  • C o d e : Code: Code:
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int a[N];
void solve(int t){
   memset(a,0,sizeof a);
   int n;
   cin>>n;
   string s;
   cin>>s;
   a[0]=1;
   for(int i=1;i<n;i++){
       if(s[i]>s[i-1]) a[i]=a[i-1]+1;
       else    a[i]=1;
   }
   printf("Case #%d: ",t);
   for(int i=0;i<n;i++)    cout<<a[i]<<" ";
   cout<<endl;
}

int main(){
   int t;
   cin>>t;
   for(int i=1;i<=t;i++){
       solve(i);
   }
   return 0;
}

Acwing.4114 垃圾桶

  • 题意: 给定 N ( 5 e 5 ) N(5e5) N(5e5) 个房子,每个房子都有两种情况:有无垃圾桶,每个人丢垃圾都会选择离自己最近的垃圾桶丢垃圾,求丢垃圾距离的总和,如果自己的房子有垃圾桶,那么距离为0。
  • 思路: 考虑从左往右做,只维护左边最近垃圾桶的信息,然后再从右往左做,只维护右边垃圾桶的信息,两次的结果取 m i n min min 即可,注意本题的总数据量达到 1 e 8 1e8 1e8 左右,不优化cin和cout会在最后一个点 T L E TLE TLE ,注意如果使用std::ios::sync_with_stdio(false)不要和printf混用,这样会造成输出错误
  • C o d e Code Code :
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
int a[N];
void solve(int t){
   memset(a,0x3f,sizeof a);
   int n;
   cin>>n;
   string s;
   cin>>s;
   int pos=0;
   bool flag=false;
   for(int i=0;i<n;i++){
       if(s[i]=='1'){
           a[i]=0;
           pos=i;
           flag=true;
       }
       else if(flag==true) a[i]=min(a[i],i-pos);
   }
   flag=false;
   for(int i=n-1;i>=0;i--){
       if(s[i]=='1'){
           a[i]=0;
           pos=i;
           flag=true;
       }
       else if(flag==true)   a[i]=min(a[i],pos-i);
   }
   ll res=0;
   for(int i=0;i<n;i++)    res+=a[i];
   cout<<"Case #"<<t<<": ";
  // printf("Case #%d: ",t);
   cout<<res<<endl;
}

int main(){
   std::ios::sync_with_stdio(false);
   cin.tie(0);
   cout.tie(0);
   int t;
   cin>>t;
   for(int i=1;i<=t;i++){
       solve(i);
   }
   return 0;
}

Acwing.3326 最大硬币数

  • 题意: 给定边长为 N ( 1000 ) N(1000) N(1000) 的方形矩阵,每个方格上给定一定数量的硬币,规定只能沿着主对角线走,起点任意,求最大硬币数
  • 思路: 枚举第一行和第一列的每一个起点的主对角线即可
  • C o d e Code Code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+10;
int g[N][N];
void solve(int t){
   int n;
   cin>>n;
   ll res=0;
   for(int i=1;i<=n;i++)
       for(int j=1;j<=n;j++)
           cin>>g[i][j];
   for(int i=1;i<=n;i++){\
       ll cur=0;
       for(int j=0;i+j<=n;j++)
           cur+=g[i+j][1+j];
       res=max(res,cur);
   }
   for(int i=1;i<=n;i++){\
       ll cur=0;
       for(int j=0;i+j<=n;j++)
           cur+=g[1+j][i+j];
       res=max(res,cur);
   }
       
           
   cout<<"Case #"<<t<<": ";
  // printf("Case #%d: ",t);
   cout<<res<<endl;
}

int main(){
  std::ios::sync_with_stdio(false);
   cin.tie(0);
   cout.tie(0);
   int t;
   cin>>t;
   for(int i=1;i<=t;i++){
       solve(i);
   }
   return 0;
}

Acwing.3325 Kick_Start

  • 题意: 给定一个长度为 N ( 1 e 5 ) N(1e5) N(1e5) 字符串,问以 KICK 开头且以 START 结尾的不同子串有多少个。
  • 思路: 与2023蓝桥杯国赛第一题填空题思路一致,处理出 START 的后缀和,然后遍历字符串,当遇到 KICK 的时候统计答案即可
  • C o d e : Code: Code:
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int a[N];
void solve(int t){
   memset(a,0,sizeof a);
   string s;
   cin>>s;
   for(int i=s.size()-5;i>=0;i--){
       if(s.substr(i,5)=="START")
           a[i]=a[i+1]+1;
       else    a[i]=a[i+1];
   }
   long long res=0;
   for(int i=0;i<s.size()-3;i++){
       if(s.substr(i,4)=="KICK")   res+=a[i+4];
   }
   printf("Case #%d: ",t);
   cout<<res<<endl;
}

int main(){
   int t;
   cin>>t;
   for(int i=1;i<=t;i++){
       solve(i);
   }
   return 0;
}

总结:除了一些细节问题整体都很简单

  • 将优化读入作为好习惯
  • 做之前要看数据范围
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值