Codeforces Round 898 (Div. 4)(A~H)题解

目录

A. Short Sort

B. Good Kid

C. Target Practice

D. 1D Eraser

E. Building an Aquarium

F. Money Trees

G. ABBC or BACB

H. Mad City


A. Short Sort

Solution:按题意模拟即可。

#include<iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include<stack>
#include <unordered_map>
using namespace std;
typedef long long  LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
const int mod = 998244353;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
LL gcd(LL a, LL b)
{
   return b ? gcd(b, a % b) : a;
}
int lowbit(int x) {return x&-x;}
void solve()
{
   string s;cin>>s;
   if(s=="abc"){
       cout<<"Yes"<<'\n';
       return;
   }
   for(int i=0;i<3;i++){
       for(int j=i+1;j<3;j++){
            string t=s;
            swap(t[j],t[i]);
            if(t=="abc"){
                cout<<"Yes"<<'\n';
                return;
            }
       }
   }
   cout<<"No"<<'\n';
}
int main()
{
   int t;cin>>t;
   while(t--) solve();
}

B. Good Kid

Solution:按题意模拟即可。

#include<iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include<stack>
#include <unordered_map>
using namespace std;
typedef long long  LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
const int mod = 998244353;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
LL gcd(LL a, LL b)
{
   return b ? gcd(b, a % b) : a;
}
int lowbit(int x) {return x&-x;}
void solve()
{
   int n;cin>>n;
   vector<LL>a(n);
   LL sum=1;
   for(int i=0;i<n;i++) {cin>>a[i];sum*=a[i];}
   LL mx=-inf;
   for(int i=0;i<n;i++){
      if(a[i]!=0)
      mx=max(sum/a[i]+sum,mx);
     else {
       sum=1;
       a[i]++;
       for(int j=0;j<n;j++){
           sum*=a[j];
       }
       cout<<sum<<'\n';
       return;
     }
   }
cout<<mx<<'\n';
}
int main()
{
   ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
   int t;cin>>t;
   while(t--) solve();
}

C. Target Practice

Solution:按题意模拟即可。

#include<iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include<stack>
#include <unordered_map>
using namespace std;
typedef long long  LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
const int mod = 998244353;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
LL gcd(LL a, LL b)
{
   return b ? gcd(b, a % b) : a;
}
int lowbit(int x) {return x&-x;}
void solve()
{
   char mp[11][11];
   for(int i=1;i<=10;i++){
       for(int j =1;j<=10;j++){
          cin>>mp[i][j];
       }
   }
   int mp1[11][11];
   for(int i=1;i<=5;i++){
       for(int j=i;j<=10-i+1;j++){
            mp1[i][j]=mp1[j][i]=i;
       }
   }
   int st=5;
   for(int i=6;i<=10;i++){
        for(int j=st;j<=10-st+1;j++){
               mp1[i][j]=mp1[j][i]=st;
        }
        st--;
   }
   int sum=0;
   for(int i=1;i<=10;i++){
       for(int j=1;j<=10;j++){
          if(mp[i][j]=='X') sum+=mp1[i][j];
       }
   }
   cout<<sum<<'\n';
}
int main()
{
   ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
   int t;cin>>t;
   while(t--) solve();
}

D. 1D Eraser

Solution:按题意模拟即可。

#include<iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include<stack>
#include <unordered_map>
using namespace std;
typedef long long  LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
const int mod = 998244353;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
LL gcd(LL a, LL b)
{
   return b ? gcd(b, a % b) : a;
}
int lowbit(int x) {return x&-x;}
void solve()
{
    int n,k;cin>>n>>k;
    string s;cin>>s;
    vector<int>pos;
    for(int i=0;i<n;i++){
         if(s[i]=='B') pos.push_back(i);
    }
    int len=pos.size();
    int cnt=0;
    for(int i=0;i<len;i++){
         int j=i;
         while(pos[j]<pos[i]+k&&j<len) j++;
         cnt++;
         i=j-1;
    }
    cout<<cnt<<'\n';
}
int main()
{
   ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
   int t;cin>>t;
   while(t--) solve();
}

E. Building an Aquarium

Solution:二分,题意是找到一个最大值使得数组每一位等于这个值,并且所有比这个数小的数和这个值的差的和不超过给定的最大值k,注意右边界可以到2e9,赛时右边界开小了wa一发。

#include<iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include<stack>
#include <unordered_map>
using namespace std;
typedef long long  LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
const int mod = 998244353;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
LL gcd(LL a, LL b)
{
   return b ? gcd(b, a % b) : a;
}
int lowbit(int x) {return x&-x;}
 vector<LL>ans(N);
 int n,x;
bool chk(LL c){
   LL sum=0;
    for(int i=0;i<n;i++){
        if(ans[i]<c) sum+=c-ans[i];
    }
    return sum<=x;
}
void solve()
{
   cin>>n>>x;
   LL mx=-inf;
   for(int i=0;i<n;i++) {
      cin>>ans[i];
      mx=max(mx,ans[i]);
   }
   LL l=1,r=2e9+10;
   LL an=-inf;
   while(l<r){
         LL mid=(l+r+1)>>1;
         if(chk(mid)) {
            l=mid;
         }
         else r=mid-1;
   }
   cout<<l<<'\n';
}
int main()
{
   ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
   int t;cin>>t;
   while(t--) solve();
}

F. Money Trees

Solution:二分+贪心+前缀和。这题颇有感触,比完赛看了很少二分做法大部分都是双指针,以为自己写了假做法(bushi。题意是找到最长的连续序列,该序列满足相邻两项前一项可以整除后一项,区间的和不能超过给定值k。明显此题可以二分长度。二分答案前预处理不满足整除关系的点并且求前缀和,二分check的时候如果该长度的最小值小于k则此长度值可行。

#include<iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include<stack>
#include <unordered_map>
using namespace std;
typedef long long  LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
const int mod = 998244353;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
LL gcd(LL a, LL b)
{
   return b ? gcd(b, a % b) : a;
}
int lowbit(int x) {return x&-x;}
vector<LL>a(N+1),h(N+1),s(N+1);
vector<int>pos(N);
LL n,k;
bool chk(int x){
      int len=pos.size();
      LL mx=inf;
      for(int i=1;i<=n;i++){
            int po=lower_bound(pos.begin(),pos.end(),i)-pos.begin();
            if(po==len){
               if(i+x-1<=n) mx=min(mx,s[i+x-1]-s[i-1]);
            }else{
                if(i+x-1<=pos[po]){
                   mx=min(mx,s[i+x-1]-s[i-1]);
                }
            }
      }
     // cout<<mx<<'\n';
      if(mx<=k) return 1;
      else return 0;
}
void solve()
{
   cin>>n>>k;
   for(int i=1;i<=n;i++) {
      cin>>a[i];
      s[i]=0;
      s[i]+=s[i-1]+a[i];
   }
   for(int i=1;i<=n;i++) cin>>h[i];
      int st=0;
   for(int i=1;i<n;i++){
        if(h[i]%h[i+1]!=0){
             pos[st++]=i;
        }
   }
   //for(auto t:pos) cout<<t<<" ";
   LL l=0,r=n,mx=-inf;
   while(l<r){
       LL mid=(l+r+1)>>1;
       if(chk(mid)){
            l=mid;
       }else{
         r=mid-1;
       }
   }
   cout<<l<<'\n';
}
int main()
{
   ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
   int t;cin>>t;
   while(t--) solve();
}

G. ABBC or BACB

Solution:题意为对于只包含AB的字符串每次 可以将“AB”替换成“BC”,“BA”替换成“CB”。最多可以替换多少次,不难发现最大值与连续A的个数有关,因为可以连续替换,并且只能选择一个B的其中一边,另一边无法替换。因此分类讨论,当结尾是B时,则最大值是所有A的个数,否则,就将所有A的个数减去最少连续A的个数即可。

#include<iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include<stack>
#include <unordered_map>
using namespace std;
typedef long long  LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
const int mod = 998244353;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
LL gcd(LL a, LL b)
{
   return b ? gcd(b, a % b) : a;
}
int lowbit(int x) {return x&-x;}
void solve()
{
    string s; cin>>s;
    bool ok=true;
    bool same=false;
    int st=0;
    vector<int> v;
    for(int i=1;i<s.size();i++){
        if(s[i]!=s[i-1]) ok=false;
        if(s[i]==s[i-1]&&s[i]=='B') same=true;
    }
    for(int i=0;i<s.size();i++){
        if(s[i]=='A') st++;
        else{
            if(st)
            v.push_back(st);
            st=0;
        }
    }
    if(st) v.push_back(st);//分段的连续A的数量
    if(ok) cout<<0<<'\n';
    else
    {
        int res=count(s.begin(),s.end(),'A');
        sort(v.begin(),v.end());
        if(s.back()=='B'){
             cout<<res<<'\n';
             return;
        }
        if(!same&&s[0]=='A') res-=v[0];
        cout<<res<<'\n';
    }
}
int main()
{
   int t;cin>>t;
   while(t--) solve();
}

H. Mad City

Solution:dfs找环+bfs找交点。很有意思的一题,题意是给定一个互相连通的图,图上两点a,b,a追b问能否找到一个方案使得b永远不会被a抓到。因为n个点n条边,因此一定会有一个环,因此我们只要让b跑到最近的环,把距离记录下来,同时a也往b离环最近的位置跑,如果a离这个位置比b近或者相等,那么就不会存在方案。否则被永远不会被抓。因为可以连续替换

#include<iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include<stack>
#include <unordered_map>
using namespace std;
typedef long long  LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
const int mod = 998244353;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
LL gcd(LL a, LL b)
{
   return b ? gcd(b, a % b) : a;
}
int lowbit(int x) {return x&-x;}
vector<int>v[N],dis(N);
vector<bool>vis(N),cir(N);
int n,a,b;
vector<int>path;
void dfs(int u,int fa){
    vis[u]=true;
    path.push_back(u);
    for(auto t:v[u]){
        if(t==fa) continue;
        if(vis[t]){
           for(int i=path.size()-1;i>=0;i--){
               cir[path[i]]=true;
               if(path[i]==t) break;
           }
        }else{
          dfs(t,u);
        }
    }
    vis[u]=false;
    path.pop_back();
}
void solve()
{
   cin>>n>>a>>b;
   for(int i=1;i<=n;i++) v[i].clear(),cir[i]=false;
   int x,y;
   for(int i=0;i<n;i++){//n个点n条边只存在一个环
       cin>>x>>y;
       v[x].push_back(y);
       v[y].push_back(x);
   }
   if(a==b) {
       cout<<"No"<<'\n';
       return;
   }
   dfs(1,-1);
   for(int i=1;i<=n;i++) dis[i]=inf;
   dis[b]=0;
   queue<int>q;
   q.push(b);
   while(!q.empty()){
      auto t=q.front();
      q.pop();
      for(auto t1:v[t]){
          if(dis[t1]>dis[t]+1){
              dis[t1]=dis[t]+1;
              q.push(t1);
          }
      }
   }
   dis[0]=inf;
   int id=0;
   for(int i=1;i<=n;i++){
        if(cir[i]&&dis[i]<dis[id]) id=i;
   }
   int ans=dis[id];//b 到环处的最短距离
    q.push(a);
    for(int i=1;i<=n;i++) dis[i]=inf;
      dis[a]=0;
   while(!q.empty()){
      auto t=q.front();
      q.pop();
      for(auto t1:v[t]){
          if(dis[t1]>dis[t]+1){
              dis[t1]=dis[t]+1;
              q.push(t1);
          }
      }
   }
   if(dis[id]<=ans){
       cout<<"No"<<'\n';
   }else cout<<"Yes"<<'\n';
}
int main()
{
   int t;cin>>t;
   while(t--) solve();
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值