9.12 div.1

Educational Codeforces Round 100 (Rated for Div. 2)

Educational Codeforces Round 101 (Rated for Div. 2)

Educational Codeforces Round 102 (Rated for Div. 2)

B - Find The Array

思路:相邻的数要有一方能整除另一方,那么一方为1的话一定可以,按奇偶位置将数分为两部分,求出a的两部分中的数的和,和大的那部分对应的b为1,另一部分为a,可以发现为1的部分带来的贡献一定是小于等于S的

#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int,int> PII;
const int N=1e4+5;
void solve(){
    int n;cin>>n;
    vector<int>a(n+1);
    int s1=0,s2=0;
    for(int i=1;i<=n;++i){
        cin>>a[i];
        if(i%2)s1+=a[i];
        else s2+=a[i];
    }
    if(s1>s2){
        for(int i=1;i<=n;++i){
            if(i%2)cout<<a[i]<<' ';
            else cout<<1<<' ';
        }
    }else{
        for(int i=1;i<=n;++i){
            if(i%2)cout<<1<<' ';
            else cout<<a[i]<<' ';
        }
    }cout<<'\n';
}
signed main(){
    int T=1;
    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}
View Code

 

C - Busy Robot

思路:模拟每一操作,对于忽略的操作,判断是否在上一操作完成和下一操作开始之前到达

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=1e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const double eps=1e-6;

void solve(){
    int n;cin>>n;
    vector<int>t(n+5),x(n+5);
    for(int i=0;i<n;++i)cin>>t[i]>>x[i];
    t[n]=1e10;
    int st=0,ed=0,las=0,ans=0,ne=0;
    for(int i=0;i<n;++i){
        if(t[i]>=ne){
            ne=t[i]+abs(x[i]-ed);
            st=ed,ed=x[i];
            las=i;
            if(ne<=t[i+1])ans++;
        }else{
            if(st>=ed){
                int r=st-t[i]+t[las];
                int l=max(ed,st-t[i+1]+t[las]);
                if(x[i]>=l&&x[i]<=r)ans++;
            }else{
                int l=st+t[i]-t[las];
                int r=min(ed,st+t[i+1]-t[las]);
                if(x[i]>=l&&x[i]<=r)ans++;
            }
        }
    }
    cout<<ans<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T=1;
    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}
View Code

D - Pairs

思路:由于a已定,那么每对中都有一个数已确定,只剩下n个数可匹配,若匹配的数大于ai,则是在x里,否则在n-x里;直接考虑极限,求x的最小值时,匹配的数向上取(从小的开始),求x的最大值时,匹配的数向下取(从大的开始)

 

#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int,int> PII;
const int N=1e4+5;
void solve(){
    int n;cin>>n;
    vector<int>st(2*n+1);
    for(int i=1,x;i<=n;++i){
        cin>>x;st[x]=1;
    }
    int c=0,l=0,r=n;
    for(int i=1;i<=2*n;++i){
        if(st[i]){
            if(c)c--;
            else l++;
        }else c++;
    }
    c=0;
    for(int i=2*n;i>=1;--i){
        if(st[i]){
            if(c)c--;
            else r--;
        }else c++;
    }
    cout<<r-l+1<<'\n';
}
signed main(){
    int T=1;
    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}
View Code

 

C - Building a Fence

思路:由于第一个和第n个已确定位置,那么从第一个位置开始,维护放的围栏底部的范围l~r,满足与前一个位置的范围距离和与当前地板的距离不超过k-1

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=1e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const double eps=1e-6;

void solve(){
    int n,k;cin>>n>>k;
    vector<int>a(n+1);
    for(int i=1;i<=n;++i)cin>>a[i];
    int l=a[1],r=a[1];
    for(int i=2;i<=n;++i){
        l=max(a[i],l-k+1);
        r=min(a[i]+k-1,r+k-1);
        if(l>r){
            cout<<"NO\n";return ;
        }
    }
    if(a[n]>=l&&a[n]<=r){
        cout<<"YES\n";
    }else cout<<"NO\n";
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T=1;
    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}
View Code

 

D - Ceil Divisions

思路:非1非2非n的数都可以由n变为1,但将n变为1最少需要18次,所以考虑用一个数a消n,令a=2x,n=ay,且n-4+x+y<=n+5,即x+y<=9;可以看出当a为8时满足

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=1e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const double eps=1e-6;

void solve(){
    int n;cin>>n;
    vector<PII>ans;
    if(n<=8){
        for(int i=3;i<n;++i){
            ans.push_back({i,n});
        }
        int t=n;
        while(t>1){
            ans.push_back({n,2});
            t=(t+1)/2;
        }
    }else{
        for(int i=3;i<n;++i){
            if(i==8)continue;
            ans.push_back({i,n});
        }
        int t=n;
        while(t>1){
            ans.push_back({n,8});
            t=(t+7)/8;
        }
        for(int i=0;i<3;++i)ans.push_back({8,2});
    }
    cout<<ans.size()<<'\n';
    for(auto v:ans){
        cout<<v.first<<' '<<v.second<<'\n';
    }
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T=1;
    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}
View Code

C - No More Inversions

思路:对于一个这样的回文串1 2 ...k... 2 1,任选两个不同的数x和y(x<y),有两种出现的情况x y y x 和 x y x,逆序数分别为1和2,并且仅当y为k时逆序数为1,那么总的逆序数为2C(k-1,2)+(k-1)=(k-1)2

可以发现a和b的第k-(n-k)到第n个数形成了回文串,且一半的数都不同,则存在的逆序数是一样的;影响b的逆序数的只有第1到第k-(n-k)-1个数,而a中的这些数对逆序数没有贡献,则p中的前k-(n-k)-1个数与a一样;由于要字典序最大,将b中的第k-(n-k)到第n个数的前半段和后半段翻转即可

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=1e4+5;
void solve(){
    int n,k;cin>>n>>k;
    for(int i=1;i<2*k-n;++i)cout<<i<<' ';
    for(int i=k;i>=2*k-n;--i)cout<<i<<' ';cout<<'\n';
}
signed main(){
    int T=1;
    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}
View Code

 

D - Program

思路:若删去一段[l,r],对于原来段中r后表示的数需要减去[l,r]的贡献,且求一段操作中存在的数的种数,相当于这一段数的max-min+1个,那么维护前后缀最大、最小值,以及前缀和即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=3e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const double eps=1e-6;

void solve(){
    int n,m;cin>>n>>m;
    string s;cin>>s;
    s.insert(s.begin(),' ');
    vector<int>sum(n+5),lma(n+5),lmi(n+5),rma(n+5),rmi(n+5);

    for(int i=1;i<=n;++i){
        if(s[i]=='-')sum[i]=sum[i-1]-1;
        else sum[i]=sum[i-1]+1;
        lmi[i]=min(lmi[i-1],sum[i]);
        lma[i]=max(lma[i-1],sum[i]);
    }
    rmi[n]=rma[n]=sum[n];
    for(int i=n-1;i>=1;--i){
        rmi[i]=min(rmi[i+1],sum[i]);
        rma[i]=max(rma[i+1],sum[i]);
    }
    int l,r;
    while(m--){
        cin>>l>>r;
        int c=sum[r]-sum[l-1];
        int mi=0,ma=0;
        if(l!=1)mi=min(lmi[l-1],mi),ma=max(ma,lma[l-1]);
        if(r!=n)mi=min(rmi[r+1]-c,mi),ma=max(ma,rma[r+1]-c);
        cout<<ma-mi+1<<'\n';
    }
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T=1;
    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}
View Code

 

posted @ 2023-09-14 13:35  bible_w  阅读(12)  评论(0编辑  收藏  举报