情人节日特辑 CODEFORCE 175 补题 (A-C)

也算是在情人节前将题目补完了,就简单讲一下三个题吧,时间不是很多,事情倒是不少,所以就要快点了,争取半个小时做完题目。
首先是A题:
https://codeforces.com/contest/2070/problem/A
这个题目是说去给我一个数字n,然后让我判断这个数字在0-n的范围里面存在有多少个 i%3==i%5的数字,那么在这里,我要先打一下表,因为这个题一看就是一个找规律的题目,所以在这里,我要做的就是去这个规律然后计数就可以了。
那么,可以知道,数字可以是0,1,2,15,16,17,这样子的数字,我们发现这些数字都是15的倍数,以及他们后面的三个数字,所以这样子就可以算出最后的结果了。那么在这里,可以知道,代码如下所示。

#include<bits/stdc++.h>
#define ll long long
using namespace std;

void sol(){
    int res=0;
    ll num;
    cin>>num;
    ll k=num/15;
    res+=k*3;
    
    if(num%15==0){
        res+=1;
    }
    else if(num%15==1){
        res+=2;
    }
    else if(num%15>=2){
        res+=3;
    }
    cout<<res<<endl;

}

int main(){
    ll T;cin>>T;
    while(T--){
        sol();
    }
}

对于B题,如下所示,在这里,他是说会有一个机器人,他会告诉你机器人的初始位置x,然后他还会告诉你机器人的指令的长度n以及在这里最后的计时器的总长度k,在这里,由于到达0,如果时间还没有结束,就会重新记录指令,这样子其实就会发现形成了一个循环了,此时,对于接下来的时间K,我们只要去计算有多少时间可以算出要经过多少次才可以完成了。当然,在这里要注意的是,如果指令结束了,但是时间没有结束,机器人就会在哪里暂停。所以在这里,可以知道如下所示。

#include<bits/stdc++.h>
#define ll long long
using namespace std;

void sol(){
    int n,x;
    ll k;
    cin>>n>>x>>k;
    vector<char> s;
    for(int i=1;i<=n;i++){
        char c;cin>>c;
        s.push_back(c);
    }

    int num=0;
    for(char c:s){
        if(c=='L'){
            x-=1;
        }
        else{
            x+=1;
        }
        num++;
        if(x==0){
            break;
        }
    }
    //指令执行完成,没有到达0
    if(x!=0){
        cout<<0<<endl;
        return;
    }
    //
    int num_L=0;
    int num_R=0;
    int rec=0;
    for(char c:s){
        if(c=='L'){
            num_L+=1;
        }
        else{
            num_R+=1;
        }
        rec++;
        if(num_L==num_R){
            break;
        }
    }
    if(num_L!=num_R){
        cout<<1<<endl;
        return;
    }

    //指令回溯到0
    ll res=0;
    k-=num;
    res++;
    res+=k/rec;
    cout<<res<<endl;

}

int main(){
    int T;
    cin>>T;
    while(T--){
        sol();
    }
}

一发直接AC。

下面这一题,比较因为回去的晚,只做了1.5小时,那么是没有时间去做的,那么在这里补一下,这个题首先翻译完题目,说是让最大的惩罚值最小,那么这个就是一眼去二分答案,那么怎么做呢,首先对于二分答案,就是要找出check函数,check函数的值就是要去检查当前的惩罚值是否满足要求,如果满足要求,那么就继续让惩罚值往更小的地方试探,否则就往更大的地方去试探。
那么对于这样子一个序列,由于我要让惩罚值最小,那么对于当前的惩罚值,如果其现在的大小小于x,我可以选择把它变为任意的颜色,因为其如果涂错的的话,也不会影响我这里的最大惩罚值,但是,如果说是大于x的,那么必须将它涂成正确的颜色,这样子才可以成立。所以我们就要检查在k次以内,是否可以把大于x的条带涂成正确的颜色。在这里,可以知道代码如下。

inline bool check(int mid){
    char last='R';
    int cnt=0;
    for(int i=0;i<n;i++){
        if(nums[i]>mid){
            if(s[i]=='B' && last!='B'){
                cnt+=1;
            }
            last=s[i];
        }
    }
    return cnt<=k;
}

最后,可以知道完整的代码

#include<bits/stdc++.h>
#define int long long
using namespace std;

vector<int>nums;
int n,k;
string s;

inline bool check(int mid){
    char last='R';
    int cnt=0;
    for(int i=0;i<n;i++){
        if(nums[i]>mid){
            if(s[i]=='B' && last!='B'){
                cnt+=1;
            }
            last=s[i];
        }
    }
    return cnt<=k;
}

inline void sol(){
    cin>>n>>k;
    cin>>s;
    nums.clear();
    for(int i=0;i<n;i++){
        int num;cin>>num;
        nums.push_back(num);
    }
    int l=0;int r=1e9+7;
    int res=-1;
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid)){
            res=mid;
            r=mid-1;
        }
        else{
            l=mid+1;
        }
    }
    cout<<res<<endl;

}

signed main(){
    int T;
    cin>>T;
    while(T--){
        sol();
    }
}
posted @ 2025-03-15 16:09  fufufuf  阅读(18)  评论(0)    收藏  举报