首页 > 其他分享 >Codeforces Round 933 (Div. 3) A-F

Codeforces Round 933 (Div. 3) A-F

时间:2024-03-12 11:55:05浏览次数:25  
标签:const int ll Codeforces long while solve 933 Div

Codeforces Round 933 (Div. 3)

A. Rudolf and the Ticket

题意:

有两个数组\(b_n\)和\(c_m\),两个数组中分别取一个数相加是否小于k,有几种方法使\(b_f\)+\(c_s\)<=k

思路:

暴力枚举所有方案,时间复杂度O(nm)

代码:

#include <bits/stdc++.h>
using namespace std ;
const int MAXN=1e5+7;
const int INF = 0x3f3f3f3f;
typedef long long ll;
#define endl "\n"

void solve(){
	int n,m,k;
    cin>>n>>m>>k;
    int b[n+1],c[m+1];
    for(int i=1;i<=n;i++){
        cin>>b[i];
    }
    for(int i=1;i<=m;i++){
        cin>>c[i];
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(b[i]+c[j]<=k){
                ans++;
            }
        }
    }
    cout<<ans<<endl;
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	int t=1;
	
	cin>>t;
	while(t--){
		solve();
	}
	
	return 0;
}

B. Rudolf and 121

题意:

有一个数组\(a_n\),有一种操作,可以选择一个下标i,操作:\(a_{i-1}\)-=1,\(a_i\)-=2,\(a_{i+1}\)-=1。可以进行任意次操作,是否可以使数组全为0

思路:

贪心,从前往后操作使\(a_{i-1}\)=0,若\(a_i\)小于0则不行

代码:

#include <bits/stdc++.h>
using namespace std ;
const int MAXN=1e5+7;
const int INF = 0x3f3f3f3f;
typedef long long ll;
#define endl "\n"

void solve(){
	int n;
    cin>>n;
    int a[n+1];
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    for(int i=2;i<n;i++){
        int t=a[i-1];
        if(t<0){
            cout<<"NO"<<endl;
            return ;
        }
        a[i]-=2*t;
        a[i+1]-=t;
    }
    if(a[n-1]==0&&a[n]==0){
        cout<<"YES"<<endl;
    }else{
        cout<<"NO"<<endl;
    }
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	int t=1;
	
	cin>>t;
	while(t--){
		solve();
	}
	
	return 0;
}


C. Rudolf and the Ugly String

题意:

删除任意字符使字符串中不含map和pie

思路:

若字符串中含有map或pie,删除字符p来同时应对mapie的特殊情况

代码:

#include <bits/stdc++.h>
using namespace std ;
const int MAXN=1e5+7;
const int INF = 0x3f3f3f3f;
typedef long long ll;
#define endl "\n"

void solve(){
	int n;
    cin>>n;
    string s;
    cin>>s;
    int ans=0;
    vector<int > mp(n+1,0);
    string t1="map";
    string t2="pie";
    for(int i=0;i<n-2;i++){
        if(mp[i]==1){
            continue;
        }
        if(s.substr(i,3)==t1){
            ans++;
            mp[i+2]=1;
        }else if(s.substr(i,3)==t2){
            ans++;
            mp[i]=1;
        }
    }
    cout<<ans<<endl;
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	int t=1;
	
	cin>>t;
	while(t--){
		solve();
	}
	
	return 0;
}

D. Rudolf and the Ball Game

题意:

给一个环,环上有n个玩家,球一开始在玩家x手上,每次抛出可以选择顺时针抛出,可以逆时针抛出,也有可能不知道往哪边抛出,求结束时球可能在哪几个玩家手上

思路:

模拟即可,每次抛出时记录球一开始可能在谁手上,可能会传到谁手上,注意去重

代码:

#include <bits/stdc++.h>
using namespace std ;
const int MAXN=1e5+7;
const int INF = 0x3f3f3f3f;
typedef long long ll;
#define endl "\n"

void solve(){
	int n,m,x;
    cin>>n>>m>>x;
    int r;
    string c;
    queue<int > Q;
    Q.push(x);
    for(int i=1;i<=m;i++){
        cin>>r>>c;
        queue <int > cnt;
        map<int ,int > mp;
        if(c[0]=='?'){
            while(!Q.empty()){
                int t=Q.front();
                Q.pop();
                if(mp[(t+r-1)%n+1]==0){
                    cnt.push((t+r-1)%n+1);
                    mp[(t+r-1)%n+1]=1;
                }
                if(mp[(t-r+n-1)%n+1]==0){
                    cnt.push((t-r+n-1)%n+1);
                    mp[(t-r+n-1)%n+1]=1;
                }
            }
        }else if(c[0]=='0'){
            while(!Q.empty()){
                int t=Q.front();
                Q.pop();
                if(mp[(t+r-1)%n+1]==0){
                    cnt.push((t+r-1)%n+1);
                    mp[(t+r-1)%n+1]=1;
                }
            }
        }else if(c[0]=='1'){
            while(!Q.empty()){
                int t=Q.front();
                Q.pop();
                if(mp[(t-r+n-1)%n+1]==0){
                    cnt.push((t-r+n-1)%n+1);
                    mp[(t-r+n-1)%n+1]=1;
                }
            }
        }
        Q=cnt;
    }
    vector<int > ans;
    while(!Q.empty()){
        ans.push_back(Q.front());
        Q.pop();
    }
    sort(ans.begin(),ans.end());
    cout<<ans.size()<<endl;
    for(int i=0;i<ans.size();i++){
        cout<<ans[i]<<" ";
    }
    cout<<endl;
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	int t=1;
	
	cin>>t;
	while(t--){
		solve();
	}
	
	return 0;
}

E. Rudolf and k Bridges

题意:

有一个河流,要造k座连续的桥,桥墩的代价为\(a_{i,j}\)+1,桥墩间的距离不能超过d,求造桥的最小代价

思路:

计算在第i行造桥的最小代价,dp即可,状态转移方程为\(dp_j\)=\(dp_{k}\)+\(a_{i,j}\)+1,k为[j-k-1,j-1],这里枚举k的话会超时,所以这里要维护单调队列来直接得到k的值(单调队列不会的话我有时间再写一篇博客),这样求出每行的最小代价。最后选择连续的k行桥,这里前缀和然后枚举就好

代码:

#include <bits/stdc++.h>
using namespace std ;
const int MAXN=1e5+7;
const long long INF = 0x3f3f3f3f3f3f3f3f;
typedef long long ll;
#define endl "\n"

void solve(){
	int n,m,k,d;
    cin>>n>>m>>k>>d;
    ll a[n+1][m+1];
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>a[i][j];
        }
    }
    vector<ll > ans;
    for(int i=1;i<=n;i++){
        vector<ll > dp(m+1,0);
        deque<int> Q; // 存储的是编号
        while(!Q.empty()){
            Q.pop_back();
        }
        dp[1]=a[i][1]+1;
        Q.push_back(1);
        for(int j=2;j<=m;j++){
            if (!Q.empty() && j - Q.front() > d+1) // 毕业
                Q.pop_front();
            dp[j]=dp[Q.front()]+a[i][j]+1;
            while (!Q.empty() && dp[Q.back()] > dp[j]) // 比新生弱的当场退役(求区间最小值把这里改成>即可)
                Q.pop_back();
            Q.push_back(j); // 新生入队
        }
        ans.push_back(dp[m]);
    }
    ll pre[n+1];
    pre[0]=ans[0];
    for(int i=1;i<n;i++){
        pre[i]=pre[i-1]+ans[i];
    }
    ll cnt=INF;
    cnt=pre[k-1];
    for(int i=k;i<n;i++){
        cnt=min(cnt,pre[i]-pre[i-k]);
    }
    cout<<cnt<<endl;
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	int t=1;
	
	cin>>t;
	while(t--){
		solve();
	}
	
	return 0;
}

F. Rudolf and Imbalance

题意:

有一个数组a,它是升序的,它的平衡性为最大的\(a_i\)-\(a_{i-1}\),有两个数组d、f,可以从两个数组中分别选择一个数相加,将\(d_i\)+\(f_j\)插入到数组a的对应位置中,使平衡性降低,这个操作最多一次。求最小的平衡性

思路:

先找出数组中使平衡性最大的两个数,需要找到\(d_i\)+\(f_j\)插入到这两个数之间,使平衡性降低,如果暴力枚举数组d和f的所有情况,时间复杂度将达到1e10,3秒肯定超时,所以这里要进行优化,先将数组d和f排序,枚举数组d,然后对数组f进行二分,使\(d_i\)+\(f_j\)接近那两个数的中间值,最后将最接近中间值的\(d_i\)+\(f_j\)加入到数组a中,再计算一遍平衡性

代码:

#include <bits/stdc++.h>
using namespace std ;
const int MAXN=1e5+7;
const int INF = 0x3f3f3f3f;
typedef long long ll;
#define endl "\n"

void solve(){
	int n,m,k;
    cin>>n>>m>>k;
    ll a[n+1],b[m+1],f[k+1];
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    for(int i=1;i<=m;i++){
        cin>>b[i];
    }
    for(int i=1;i<=k;i++){
        cin>>f[i];
    }
    ll mx=0;
    int mx_l=0,mx_r=0;
    int count=0;
    for(int i=2;i<=n;i++){
        if(a[i]-a[i-1]>mx){
            count=1;
            mx=a[i]-a[i-1];
            mx_l=i-1;
            mx_r=i;
        }else if(a[i]-a[i-1]==mx){
            count++;
        }
    }
    if(count>1){
        cout<<mx<<endl;
        return ;
    }
    sort(b+1,b+1+m);
    sort(f+1,f+1+k);
    ll ans=0;
    for(int i=1;i<=m;i++){
        //zuocebianjie
        int left = 1;
        int right = k+1; // 注意
        ll target=(a[mx_l]+a[mx_r])/2;
        while (left < right) { // 注意
            int mid = (left + right) / 2;
            if (b[i]+f[mid] == target) {
                right = mid;
            } else if (b[i]+f[mid] < target) {
                left = mid + 1;
            } else if (b[i]+f[mid] > target) {
                right = mid; // 注意
            }
        }
        int res=left;
        if(res>=1&&res<=k){
            int t=b[i]+f[res];
            if(t>=a[mx_l]&&t<=a[mx_r]){
                if(max(t-a[mx_l],a[mx_r]-t)<max(ans-a[mx_l],a[mx_r]-ans)||ans==0){
                    ans=t;
                }
            }
        }

        //youce
        left=1;
        right=k+1;
        target=(a[mx_l]+a[mx_r]+1)/2;
        while (left < right) {
            int mid = (left + right) / 2;
            if (b[i]+f[mid] == target) {
                left = mid + 1; // 注意
            } else if (b[i]+f[mid] < target) {
                left = mid + 1;
            } else if (b[i]+f[mid] > target) {
                right = mid;
            }
        }
        res=left-1;
        if(res>=1&&res<=k){
            int t=b[i]+f[res];
            if(t>=a[mx_l]&&t<=a[mx_r]){
                if(max(t-a[mx_l],a[mx_r]-t)<max(ans-a[mx_l],a[mx_r]-ans)||ans==0){
                    ans=t;
                }
            }
        }
    }
    if(ans==0){
        cout<<mx<<endl;
    }else{
        a[0]=ans;
        sort(a,a+1+n);
        ll cnt=0;
        for(int i=1;i<=n;i++){
            cnt=max(cnt,a[i]-a[i-1]);
        }
        cout<<cnt<<endl;
    }

}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	int t=1;
	
	cin>>t;
	while(t--){
		solve();
	}
	
	return 0;
}

标签:const,int,ll,Codeforces,long,while,solve,933,Div
From: https://www.cnblogs.com/beater/p/18067988

相关文章

  • SMU Winter 2024 div2 ptlks的周报Week 5(3.4-3.10)
    维护子树的全部子树的权值和时,需要用到树的DFS序列,树的每个子树都对应DFS序列中的连续一段黄金树影题意:给定一棵树及每个节点的权值,给定一组操作,输入1ax,表示节点a权值加上x;输入2a,表示询问节点a的子树权值和(包含a)。考虑到树的DFS序列,则问题转变为对某个序列维护区间和以......
  • Codeforces Round 656 (Div. 3) F. Removing Leaves
    ProblemDescription给出一棵\(n\)个节点的无根树。你可以进行以下操作:选择\(k\)个共同父节点的叶子节点,将\(k\)个节点和与父节点相连的边删去。求最大操作次数。Input第一行输入一个整数\(t\)\((1\let\le2\times10^4)\),表示测试组数。接下来每组测试数据第......
  • A. k-th divisor
    https://codeforces.com/problemset/problem/762/AThisisaeasyproblembasedonnumbertheory.Wejustsimplyiterateifrom1tothevalueofsqrt(n),andcheckifnisdivisblebythevalueofiandfindallofitsdivisors,thensortthemandgetthea......
  • Add, Divide and Floor
    我们不妨将这个式子看做取中点,然后就会发现每次操作不改变相对大小,然后看这篇洛谷题解解释一下他这个合理性,主要是害怕讨论每次操作后的\(a,b\)的奇偶而已这里其实官方题解给出了一个提示我们设最开始的\(b-a=x\),那么根据这篇洛谷题解,而每次操作要么让\(x=\lfloor\frac{x}{2}......
  • 二进制变化_cf1+2_C. Divisor Chain
    目录题目概述思路想法参考代码做题反思题目概述原题参考:C.DivisorChain给出一个数x,可以对他做以下的变换若y是x的除数,x-=y任意的y不能使用超过两次可以证明的是,对于任意的数,都可以在1000次操作内将其变成1,请输出将x变为1的操作次数与过程思路想法首先是如果随机除以因......
  • Codeforces Round 932 (Div. 2)
    目录写在前面ABCDE写在最后写在前面比赛地址:https://codeforces.com/contest/1935。被精心构造的C的样例鲨了的一集。妈的天使骚骚☆REBOOT完全就是他妈拔作啊我草,要是被人知道我他妈推了全线要被笑话一辈子吧、、、A签到。操作偶数次,则答案仅可能为s或reverse(s)+s......
  • CF contest 1935 Round 932 (Div. 2) A-D题解
    CodeforcesRound932(Div.2)A-D题解CodeforcesRound932(Div.2)绪言很菜,AB速度慢,卡在C,想DP,但是时间优化不下来,说服自己\(2\times10^3\)能过\(n^3\),D稍微简单,但是没看D,遂掉分。A.EntertainmentinMAC给你一个字符串\(s\)和一个偶整数\(n\)。你可以对它进行两种运......
  • Codeforces 专区
    CodeforcesRound#932(Div.2)怎么只会A啊。\(\text{ProblemA}\)题目大意对于一个字符串\(s\),可以进行\(n\)次操作(\(n\)为偶数),每次操作有两种形式:令\(t\)为\(s\)的反串,\(s=s+t\)。令\(t\)为\(s\)的反串,\(s=t\)。要求操作完后\(s\)的字典序最小,并输......
  • Though Our Paths May Diverge(JSOI 2024 游记)
    Isn’titsupposedtobesunnynow?且当是JSOI2024的游记吧。省选前的精神状态处于一种微妙的平衡。确实也不断在给自己心理暗示,自己有省队水平,但是其实无论是哪边的模拟打得都属于比较稀烂的水平,有的时候真的是一题不会签不上到。跟不上zhy和黄色蜜蜂的节奏啊,大概就......
  • Codeforces Round 931div2补题
    B.YetAnotherCoinProblem真[https://www.bilibili.com/video/BV1o2421M7pV/]不同硬币之间有倍数关系,使得一定数量后的小硬币可以被大硬币替代达到最优方案,而每个小硬币在最优下有可能的数量如下,进行枚举后找到最优方案。1:不多于2个(3个1会被3替代)3:不多于一个(2个3......