首页 > 其他分享 >Codeforces Round #843 (Div. 2)

Codeforces Round #843 (Div. 2)

时间:2023-12-29 19:11:06浏览次数:27  
标签:843 int Codeforces while del 字符串 maxn Div dis

安利一个叫codeforces better的插件  https://greasyfork.org/zh-CN/scripts/465777-codeforces-better

今天装了后使用cf体验非常舒适

=====

A.Gardener and the Capybaras (easy version)

问字符串s能否切分成3个字符串a、b、c,且满足a<=b&&c<=b或者b>=a&&b>=c

s长度<=100,暴力枚举即可

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
void solve(){
    string s;
    cin>>s;
    int n=s.length();
    for(int i=0;i<n;i++)
     for(int j=i+1;j<n;j++)
      for(int k=j+1;k<n;k++) 
    {
        string a,b,c;
        a="";b="";c="";
        for(int h=0;h<=i;h++) a=a+s[h];
        for(int h=j;h<=k-1;h++) b=b+s[h];
        for(int h=k;h<n;h++) c=c+s[h];
        if((!a.length())||(!b.length())||(!c.length())) continue;
        
        if(a<=b&&c<=b){
            cout<<a<<" "<<b<<" "<<c<<endl;
            return ;
        }
        if(b<=a&&b<=c){
            cout<<a<<" "<<b<<" "<<c<<endl;
            return;
        }
     }
}
int main(){
    int t;
    cin>>t;
    while(t--){
        solve();
    }
}

A2.A2 - Gardener and the Capybaras (hard version)

题意同上,但是s的长度变成2e5

那肯定有一些特殊的解法

考虑什么情况下字符串最小,s仅由a、b构成,显然如果存在a,那么a肯定最小

但是a可能出现在两端或者中间,讨论一下

  • 如果出现在中间,记出现的位置为pos,直接令字符串b="a"即可,字符串a=s[0:pos-1],字符串c=s[pos+1,|s|-1]
  • 如果出现在两端,则中间串必然为bbb...bbb,令字符串a=s[0],字符串c=s[|s|-1],字符串b=s[1,|s|-2],这样做一定是对的,证明:  
    • 不失一般性地令s[0]="a",则s[|s|-1]若="a",中间的串必然大于两边的串
    • 若s[|s|-1]="b",则中间的串必然大于两边的串    
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
void solve(){
    string s;
    cin>>s;
    int n=s.length();
    
    int flag=0;
    for(int i=1;i<n-1;i++)
       if(s[i]=='a') {
          flag=i;
          break;
       }
    
    if(flag){
        for(int i=0;i<flag;i++) cout<<s[i];
        cout<<" a ";
        for(int i=flag+1;i<n;i++) cout<<s[i];
        cout<<endl;
    }
    else {
        cout<<s[0]<<" ";
        for(int i=1;i<n-1;i++) cout<<s[i];
        cout<<" "<<s[n-1]<<endl;
    }
}
int main(){
    int t;
    if("bb">"b") cout<<1<<endl;
    cin>>t;
    while(t--){
        solve();
    }
}

C.C - Interesting Sequence

给定n和x(n<=1e18),要求最小的m使得 n&(n+1)&(n+2)..&m=x

一开始直接做差,令del=n-x,则del在二进制表示下有1的位置必是x有1的位置的子集(因为&只会使n的1减少,&运算是单调不增的)

那么考虑del的最高位,显然要把这位的1消掉必须要加到这位会被进位

又因为这个过程是不断累加的,所以最高位之前的1也都会被抹去

所以只要在n中把del出现过的1都抹去,再在最高位+1的地方补1即可

不过这样写要特判一些东西:

显然

  1. x<=n
  2. del是n的子集
  3. 要保证del是x的某个后缀(对应“最高位之前的1也都会被抹去”)
  4. 补位时不能进位。这点很重要,有点难考虑到。如果补位会进位的话说明n的这位也会变成0,就无法得到x
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
vector<int>v[maxn];
int cntx[maxn],cntdel[maxn],k[maxn];
typedef long long ll;
void solve(){
    ll x,y;
    cin>>x>>y;
    if(y>x) {
        cout<<-1<<endl;
        return ;
    }

    if(x==y) {
        cout<<x<<endl;
        return;
    }

    ll del=x-y;
    int flag=1;
    for(ll i=63;i>=0;i--){
        if((del>>i)&1){
            if(((x>>i)&1)==0) flag=0;
        }
    }
    ll tmpx=x,tmpdel=del;
    int cnt_x=0,cnt_del=0;
    while(tmpx){
        cnt_x++;cntx[cnt_x]=tmpx%2;
        tmpx>>=1;
    }
    while(tmpdel){
        cnt_del++;cntdel[cnt_del]=tmpdel%2;
        tmpdel>>=1;
    }
    for(int i=1;i<=cnt_del;i++){
        if(cntx[i]==1&&cntdel[i]==0){
            flag=0;
        }
    }
    
    if(flag==0) {
        cout<<-1<<endl;
        return;
    }
    
    if(del!=x){
        ll pos=log2(del),ans;
        ans=pow(2,pos+1);
        for(int i=pos+3;i<=cnt_x;i++) {
            if(cntx[i]==1) ans+=(1ll<<(i-1));
        }
        if(cntx[pos+2]==1) {
            cout<<-1<<endl;
            return;
        }
        cout<<ans<<endl;
    }
    else {
        cout<<(ll)pow(2,(ll)log2(del)+1)<<endl;
    }
}
int main(){
    
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin>>t;
    while(t--){
        solve();
    }
}

D.D - Friendly Spiders

经典图论,两个数之间gcd!=1即可连边,代价为1。问从s到t的最小代价。

跟gcd有关的话很容易考虑到枚举因数,我最开始考虑的是按照每个质因数去分类,但是这样往下推会遇到无法解决的问题

正解是按照因数去分类(是的,直接枚举因子,略暴力了。。),对于每个点,和自己的因子连一条边权为1的边,这里的因子是新建的虚点

然后bfs,答案为最短路/2+1

#不知道为啥一直wa15,饿了,先去吃个饭,然后再填坑
#include<bits/stdc++.h> using namespace std; const int N=1e6+5; const int inf=1e9+5; vector<int>fac[N],e[N]; int dis[N],vis[N],a[N],pre[N]; void init(){ for(int i=2;i<N;i++){ if(vis[i]) continue; for(int j=i;j<N;j+=i){ vis[j]=true; fac[j].push_back(i); } } } void solve(){ int n;cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; int s,t;cin>>s>>t; for(int i=1;i<=2*n;i++) e[i].clear(),dis[i]=inf,pre[i]=0; for(int i=1;i<=n;i++){ int x=a[i]; for(auto c:fac[x]){ e[n+c].push_back(i); e[i].push_back(n+c); } } queue<int>q; dis[s]=0; q.push(s); while(!q.empty()){ int x=q.front(); q.pop(); for(auto to:e[x]){ if(dis[to]>dis[x]+1){ dis[to]=dis[x]+1; q.push(to); pre[to]=x; } } } if(dis[t]==inf){ cout<<-1<<endl; return; } cout<<dis[t]/2+1<<endl; vector<int>ans; int at=t; while(at){ if(at<=n) ans.push_back(at); at=pre[at]; } for(int i=ans.size()-1;i>=0;i--) cout<<ans[i]<<" "; cout<<endl; } int main(){ ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); init(); int t=1; while(t--){ solve(); } }

 

标签:843,int,Codeforces,while,del,字符串,maxn,Div,dis
From: https://www.cnblogs.com/liyishui2003/p/17935553.html

相关文章

  • [Codeforces] CF1538F Interesting Function
    CF1538FInterestingFunction题目传送门题意给定两个正整数\(l,r\)(\(l<r\)),将\(l\)不断加\(1\)直到\(l=r\),求出这一过程中\(l\)发生变化的位数总数。位数变化指:\(l=909\),将\(l+1\)后有\(2\)位数字发生变化。\(l=9\),将\(l+1\)后也有\(2\)位数字发生变......
  • codeforces比赛(1):codeforces 918_div4
    A、OddOneOut跳转原题点击此:A题地址1、题目大意  给你三个数,其中两个是相等的,问你还有一个不相等的数是多少。2、题目解析  直接暴力枚举即可,只要找到两个数相等,那么答案就是另一个数。#include<bits/stdc++.h>usingnamespacestd;intT;inta,b,c;voidsol......
  • Codeforces Round 917 (Div. 2)
    A.LeastProduct存在\(a[i]=0\),\(min=0\),不需要任何操作。负数个数为偶数(包括0),\(min=0\),把任意一个改为\(0\)。负数个数为奇数,\(min=\proda[i]\),不需要任何操作。voidsolve(){ intn; cin>>n; vector<int>b,c,d; for(inti=0;i<n;++i){ in......
  • [Codeforces] CF1536C Diluc and Kaeya
    CF1536CDilucandKaeya题意题目传送门给你一个字符串\(S\),其中只包含'K'或'D'两种字符,要求划分这个字符串使得各部分的\(n(D):n(K)\)相同,其中\(n(D)\)表示\(S\)中字符'D'出现的个数,最大化划分后形成的组数。求出\(S\)的所有前缀中的上述答案。思路注意到,如......
  • codeforces刷题(1100):1901B_div2
    B、ChipandRibbon跳转原题点击此:该题地址1、题目大意  存在一条由n个单元格组成的带子。chip可以做两个操作:1、由\(i\)走到\(i+1\),但是不能走到\(i-1\);2、可以传送到任意位置,包括传送到原地。每到一个单元格,该单元格的数值+1(初始为0)。最开始chip在从第一格开始走起(题......
  • codeforces刷题(1100):1902B_div2
    B、GettingPoints跳转原题点击此:该题地址1、题目大意  Monocarp为了完成总共n天的某学期的p学分任务。Monocarp每天可以选择两种度过方式:上一次课和完成最多两个任务或者休息一天。其中上课获得l学分,每个任务获得t学分,其中任务不可以重复接取,并且每周获得一个新的任务(第一......
  • 实现div元素滚动条自动滚动到最底部(或最顶部)
    css属性 Overflow可以实现溢出显示滚动条overflow:scroll;或overflow-y:autooverflow-x:auto 实现div元素滚动条默认滚动到最底端使用场景:聊天信息框需要了解几个属性和方法:scrollHeight:元素高度(包含滚动条隐藏部分)clientHeight:元素可视高度(不包含滚动......
  • Pinely Round 3 (Div. 1 + Div. 2)
    A.DistinctButtons#include<bits/stdc++.h>usingnamespacestd;voidsolve(){ intn; cin>>n; inta=0,b=0,c=0,d=0; for(inti=1;i<=n;i++){ intx,y; cin>>x>>y; if(x>0)a=1; if(y>0)b=1; if(x<0)c=1; if(y<......
  • 「题解」Codeforces 1427G One Billion Shades of Grey
    感谢127的指导/ll\(|h_u-h_v|=\max(0,h_u-h_v)+\max(0,h_v-h_u)\),那么可以把它看成这样的问题:\[\min\{\sum_{(u,v)}\max(0,h_u-h_v+w_{u,v})c_{u,v}\}\]对偶一下,问题就变为:如果两个格子相邻就互相连容量为\(c_{u,v}=1\),费用为\(w_{u,v}=0\)的边,跑最大费用循环流。为了限......
  • 记一次el-checkbox包裹一层div,点击div勾选复选框,点击复选框却没反应的bug
    <divclass="account-item"v-for="iteminaccountList":key="item.id":class="[{'is-select-mode':isSelectMode},{'is-select':item.isSelect}]"@click="selectItem......