Codeforces Round 828 (Div. 3) A~E

A - Number Replacement

题意:

给定两组字符串,要求相同数字下的字符一致

思路:

map<int,char> mp set<int> t;

代码:

/*
 * @Author       : 徐婧怡
 * @LastEditTime : 2024-01-10 14:29:06
 */
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ff first
#define ss second 

void solve(){
    int n;cin>>n;
    vector<int> a(n);
    set<int> t;
    map<int,char> mp;
    for(int i=0;i<n;i++)  cin>>a[i];
    string s;cin>>s;
    for(int i=0;i<n;i++){
        if(t.count(a[i])==0) {
            t.insert(a[i]);
            mp[a[i]]=s[i];
        }
        else{
            if(s[i]!=mp[a[i]]) {
                cout<<"no"<<endl;
                return ;
            }
        }
    }
    cout<<"yes"<<endl;
}

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

    int test;
    cin>>test;while(test--)
    solve();
    return 0;
}
B - Even-Odd Increments

题意:

两个操作,对给定字符串的奇数值上加x|偶数值上加x

思路:

奇数+奇数=偶数 偶数+偶数=偶数 奇数+偶数=奇数 cnt记每次更改后的奇数的个数

代码:

/*
 * @Author       : 徐婧怡
 * @LastEditTime : 2024-01-10 14:44:09
 */
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ff first
#define ss second 

void solve(){
    int n,q;cin>>n>>q;
    vector<int> a(n+1);
    int sum=0,cnt=0;
    for(int i=0;i<n;i++) {
        cin>>a[i];
        sum+=a[i];
        if(a[i]%2) cnt++;//奇数个数
    }
    while(q--){
        int f,x;cin>>f>>x;
        if(f==1){ //加奇数上
            sum+=cnt*x;
            if(x%2) cnt=0;
        }
        else{//加偶数上
            sum+=(n-cnt)*x;
            if(x%2) cnt=n;
        }
        cout<<sum<<endl;
    }
}

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

    int test;
    cin>>test;while(test--)
    solve();
    return 0;
}
C - Traffic Light

题意:

求对于某个字符,保证一定能过红绿灯的最少秒数

思路:

rrrgg 循环遍历,两个g之间只记最远的那个r需要的秒数,其他r所需要的秒数一定小于该值(因为是顺序进行的)。 注意降低复杂度!

代码:

/*
 * @Author       : 徐婧怡
 * @LastEditTime : 2024-01-10 15:54:26
 */
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ff first
#define ss second 

void solve(){
    int n;char c;
    cin>>n>>c;
    string s;cin>>s;
    int ansr=0,ansy=0;
    int flagr=0,flagy=0;
    for(int i=0;i<n;i++){
        if(s[i]=='g') flagr=0,flagy=0;  //注意降低复杂度!
        else if(s[i]=='r' && (flagr==0)){
            int j=i,cnt=0;
            while(s[j]!='g'){
                cnt++;
                if(j==n-1) j=0;
                else j++;
            }
            ansr=max(ansr,cnt);
            flagr=1;
        }
        else if(s[i]=='y'&& flagy==0){
            int j=i,cnt=0;
            while(s[j]!='g'){
                cnt++;
                if(j==n-1) j=0;
                else j++;
            }
            ansy=max(ansy,cnt);
            flagy=1;
        }
    }
    if(c=='r') cout<<ansr<<endl;
    else if(c=='y') cout<<ansy<<endl;
    else cout<<0<<endl;
}

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

    int test;
    cin>>test;while(test--)
    solve();
    return 0;
}
D - Divisibility by 2^n

题意:

ai*i 求最少需要多少次操作使得所有ai相乘可以整除2^n

思路:

先对于ai求可以整除多少个2(__builtin_ctzll(a[i])--即二进制末尾有多少个0),然后从最大的下标开始计算(__builtin_ctzll(i)),边加边判断是否大于n

二进制表示最低位有多少个连续的0=最多可以被多少个2整除 内置函数!!!

代码:

/*
 * @Author       : 徐婧怡
 * @LastEditTime : 2024-01-10 18:04:09
 */
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ff first
#define ss second 
#define lowbit(x) x&(-x)

void solve(){
   int n;cin>>n;
   vector<int> a(n+1);
   int ans=0,cnt=0;
   for(int i=1;i<=n;i++) {
    cin>>a[i];
    cnt+=__builtin_ctzll(a[i]); //x的最低位有多少个0
   }
   vector<int> p;
   for(int i=1;i<=n;i++) p.emplace_back(__builtin_ctzll(i));
   sort(p.begin(),p.end(),[](int a,int b){return a>b;});
   for(int x:p){
    if(cnt>=n) {
        cout<<ans<<endl;
        return ;
    }
    ans++;
    cnt+=x;
   }
   if(cnt>=n) cout<<ans<<endl;
   else cout<<-1<<endl;
}

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

    int test;
    cin>>test;while(test--)
    solve();
    return 0;
}
E - Divisible Numbers (easy version)

题意:

给定a,b,c,d四个正整数(a<c和b<d),找出任意一对x和y,a<x<=c,b<y<=d且x*y能被a*b整除。

思路:

因为x*y可以整除a*b,那么x*y可以整除a的因子*b的因子。故先将a的因子和b的因子两两组和相乘去重,因为要是ab的倍数,至少是ab,故tmp=ab/x,在a~c和b~d中分别找x和tmp的最小公倍数,找到即满足题意。

因子的求法

代码:

/*
 * @Author       : 徐婧怡
 * @LastEditTime : 2024-01-11 15:56:29
 */
#include<bits/stdc++.h>
using namespace std;
#define int long long

void solve(){
    int a,b,c,d;cin>>a>>b>>c>>d;
    vector<int> va,vb;
    for(int i=1;i*i<=a;i++){//求因子不会重复求
        if(a%i==0){
            va.emplace_back(i);
            if(a/i!=i) va.emplace_back(a/i);
        }
    }
    for(int i=1;i*i<=b;i++){
        if(b%i==0){
            vb.emplace_back(i);
            if(b/i!=i) vb.emplace_back(b/i);
        }
    }
    vector<int> vv;
    set<int> s;
    for(int x:va){
        for(int y:vb){
            if(s.count(x*y)==0) {
                s.insert(x*y);
                vv.emplace_back(x*y);
            }
        }
    }
    for(int p:vv){
        int q=(a*b)/p;
        int x=((a/p)+1)*p,y=((b/q)+1)*q;
        if((x<=c)&&(y<=d)){
            cout<<x<<" "<<y<<endl;
            return ;
        }
    }
    cout<<-1<<" "<<-1<<endl;
}

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值