Acwing蓝桥杯集训·题解week3

炮弹

按照题意模拟:
注意两点:
1.死循环,如果存在两个能量为0跳板,就会互相弹跳,停不下来,设置一个合理的循环上限,防止超时
2.时间复杂度:在最坏的情况下
k最开始为1,跳n次,k为2时,跳2/n次.....
所以在最坏的情况下时间复杂度\(O(\sum_{i=1}^{n}\frac{n}{i})=O(nlnn)\)是调和级数的时间复杂度

点击查看代码
#include<bits/stdc++.h>

using namespace std;

int n,s;
const int maxn=1e5+10;
struct node{
    int q,v;
}e[maxn];
int nex=1;
int ans=0;
bool flag[maxn];
int check[maxn][3];
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n>>s;
    for(int i=1;i<=n;++i) cin>>e[i].q>>e[i].v;
    bool book=1;
    int cnt=0;
    while(s>=1  && s<=n && cnt<=n*26){
    //    cout<<s<<endl;
        
        if(e[s].q==0){
            book=!book;
            nex+=e[s].v;
        }
        else {
            if(e[s].v<=nex && flag[s]==0)++ans,flag[s]=1;
        }s+=book?nex:(-1)*nex;
        ++cnt;
    }    
    cout<<ans<<endl;
    return 0;
}

平衡细菌

差分好题:

一旦从差分的角度思考该问题就相当简单,
\([l,n]\)依次加n-l,n-l+1,....,n
从差分的角度,差分数组b[l+1,n]的均+1
再差分一次,差分数组c[l]++和c[n+1]--

那么题意转化成差分的形式就是,经过多少次操作后,a全部为0,同时b全部为0,也就是c全部为0
所以操作一次对c数组的影响就是c[l]++,因此答案就是c数组的总和

注意因为有可能加的也是负数,我们统计c中数值取绝对值

点击查看代码
#include<bits/stdc++.h>

using namespace std;

#define int long long 
const int maxn=2e5+10;
int n;
int a[maxn];
int b[maxn];
int c[maxn];
signed main(){
    cin>>n;
    for(int i=1;i<=n;++i) cin>>a[i];
    int ans=0;
    for(int i=1;i<=n;++i){
        b[i]=a[i]-a[i-1];
        c[i]=b[i]-b[i-1];
        ans+=abs(c[i]);
    }
    cout<<ans<<endl;
    return 0;
    
}

回文游戏

思维题

谁先取完,谁赢

首先可以知道的是0 ~ 9肯定是回文数,所以轮到一个的数字是0~9时,就赢了

对于博弈的过程,每个人都想赢,所以不会想着取一个很大回文数,因为这样结果是很随机,没有把握,所以每个人尽量选择,一个0 ~ 9的数

对于一个末尾不是0的数,那么贝尔可以选取石使得末尾为0,埃尔希就会任意选择一个不为0且不大于9的数,如此轮回,最后贝尔会使石头变为0,赢得胜利,反之埃尔希赢

点击查看代码
#include<bits/stdc++.h>

using namespace std;
int t;

int n;
string s;
void solve(){
    cin>>s;    if(s[s.length()-1]=='0') puts("E");
    else puts("B");
    return ;
    
}
int main(){
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}

牛奶交换

最麻烦的事情,这是个环,需要特别注意

只有出现RL的时候,牛奶会在这两个捅之间循环,R左边的牛奶都会过来,L右边的牛奶也都会过来,记录每一边的牛奶,如果比时间少,那么全都损失,如果比时间多,那么只会损失时间数量的牛奶

点击查看代码
#include<bits/stdc++.h>

using namespace std;
long long  n,m;
string s;

const int maxn=2e5+10;
long long a[maxn];
long long ans=0,tot=0;
int main(){
    cin>>n>>m;
    cin>>s;s=" "+s;
    for(int i=1;i<=n;++i) cin>>a[i],tot+=a[i];
   long long sum1=0,sum2=0;
    bool book=0;
    for(int i=1;i<n;++i){
        if(s[i]=='R' && s[1+i]=='L') book=1;
        if(s[i]=='L' && s[i+1]=='R') book=1;
    }
    if(!book){
        cout<<tot<<endl;return 0;
    }
    for(int i=1;i<=n;++i){
        if(s[i]=='R' && s[(i)%n+1]=='L'){
            int j=i-1;
            while(s[j]=='R'){
                sum1+=a[j];
                --j;
                if(j==0) j=n;
            }
            j=i%n+2;
            while(s[j]=='L' && j<=n){
                sum2+=a[j];
                ++j;
                if(j==n+1) j=1;
            }
        	ans+=min(sum1,m)+min(sum2,m);
        	sum1=0,sum2=0;
        }
    }
    cout<<tot-ans<<endl;
    return 0;
}

最大限度地提高生产力

由于时间的数据范围不大,我们可以直接用后缀和预处理某个时刻之后还开着的农场,查询时就可以以O(1)的时间查询还开着的农场

点击查看代码
#include<bits/stdc++.h>

using namespace std;
int n,q;
const int maxn=2e6+10;
int t[maxn],c[maxn];
int sum[maxn];

int v,s;
int main(){
    cin.tie(0);cout.tie(0);
    ios::sync_with_stdio(0);
    memset(sum,0,sizeof(sum));
    cin>>n>>q;
    for(int i=1;i<=n;++i) cin>>c[i];
    for(int i=1;i<=n;++i){
        cin>>t[i];
        if(c[i]-t[i]-1>=0)sum[c[i]-t[i]-1]++;
    }
    for(int i=2e6;i>=0;--i) sum[i]+=sum[i+1];
    while(q--){
        cin>>v>>s;
        if(sum[s]>=v) puts("YES");
        else puts("NO");
    }
    return 0;
}
posted @ 2025-03-22 13:37  归游  阅读(9)  评论(0)    收藏  举报