AtCoder Beginner Contest 158

传送门

A - Station and Bus

#include <bits/stdc++.h>
using namespace std;
char s[5];
int main() {
    //freopen("in.txt","r",stdin);
    scanf("%s",s);
    int a=0,b=0;
    for(int i=0;s[i];i++) {
        if(s[i]=='A') a++;
        else b++;
    }
    printf("%s
",a&&b?"Yes":"No");
    return 0;
}
A.cpp

B - Count Balls

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main() {
    //freopen("in.txt","r",stdin);
    ll n,a,b;
    scanf("%lld%lld%lld",&n,&a,&b);
    printf("%lld
",n/(a+b)*a+min(n%(a+b),a));
    return 0;
}
B.cpp

C - Tax Increase

题意:找到最小的正整数x,满足$left lfloor x*0.08 ight floor = A and   left lfloor x*0.1 ight floor = B$,若不存在,输出-1。

数据范围:$1 leq A leq B leq100$

题解:暴力枚举x判断即可,至少要枚举到1000。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main() {
    //freopen("in.txt","r",stdin);
    int a,b;
    scanf("%d%d",&a,&b);
    bool f=false;
    for(int i=1;i<=1500;i++) {
        if(i*8/100==a&&i/10==b) {
            printf("%d
",i);
            f=true;
            break;
        }
    }
    if(!f) printf("-1
");
    return 0;
}
C.cpp

D - String Formation

题意:给一个字符串S,进行Q次操作,有翻转字符串、字符串开头加一个字符、字符串结尾加一个字符三种操作,输出最终的字符串。

数据范围:$1 leq left | S ight | leq 10^{5},1 leq Q leq 2 imes 10^{5}$

题解:根据当前状态是否翻转和加字符操作来判断加在开头还是结尾,最后根据最终状态输出字符串(正序 or 逆序)。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=3e5+5;
char s[N],a[N],b[N],c[5];
int main() {
    //freopen("in.txt","r",stdin);
    int n,q,t=0,ta=0,tb=0;
    scanf("%s%d",s,&q),n=strlen(s);
    for(int i=0,op;i<q;i++) {
        scanf("%d",&op);
        if(op==1) t^=1;
        else {
            scanf("%d%s",&op,c),op--;
            if(op^t) b[tb++]=c[0];
            else a[ta++]=c[0];
        }
    }
    if(!t) {
        for(int i=ta-1;i>=0;i--) printf("%c",a[i]);
        for(int i=0;i<n;i++) printf("%c",s[i]);
        for(int i=0;i<tb;i++) printf("%c",b[i]);
    }
    else {
        for(int i=tb-1;i>=0;i--) printf("%c",b[i]);
        for(int i=n-1;i>=0;i--) printf("%c",s[i]);
        for(int i=0;i<ta;i++) printf("%c",a[i]);
    }
    return 0;
}
D.cpp

E - Divisible Substring

题意:给一个长度为N的字符串S,以及一个质数P,求有多少个子串在十进制下对P取模为0。

数据范围:$1 leq N leq 2 imes 10^{5},2 leq P leq 10^{4}$

题解:首先可以得知$10^{x} mod P eq 0 (P eq 2 and   P eq 5)$,那么对于$S[l...r]$子串,当且仅当$S[l...N] equiv S[r...N] (mod P)$成立时,满足要求。

证明如下:$S[l...r] imes 10^{r-l} = S[l...N]-S[r...N] $,若$S[l...N]-S[r...N] equiv 0(mod P)$,由于$10^{x} mod P eq 0$,可以得出$S[l...r] mod P =0$,若 $S[l...r] equiv 0(mod P)$,显然$S[l...r] imes 10^{r-l}  mod P = 0$。

可以对P=2,P=5进行特判,然后倒着遍历字符串,每次加上之前余数和当前余数相同的个数。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+5;
char s[N];
unordered_map<int,int> ma;
int main() {
    //freopen("in.txt","r",stdin);
    int n,p;
    scanf("%d%d%s",&n,&p,s+1);
    ll ans=0;
    if(10%p==0) {
        for(int i=1;i<=n;i++) {
            if((s[i]-'0')%p==0) ans+=i;
        }
    }
    else {
        int res=0,t=1;
        for(int i=n;i>=1;i--) {
            ma[res]++;
            res=(res+(s[i]-'0')*t)%p;
            t=t*10%p;
            ans+=ma[res];
        }
    }
    printf("%lld
",ans);
    return 0;
}
E.cpp

F - Removing Robots

题意:N个机器人,第i个机器人在Xi位置上,若一个机器人被激活,则它将向右移动Di,若途径别的机器人,则该机器人也将被激活,求可以得到多少个没被激活的机器人的集合(激活次数不限)(对998244353取模)。

数据范围:$1leq N leq 2 imes 10^{5},-10^{9}leq Xi leq 10^{9},1 leq Di leq 10^{9}$

题解:首先先将N个机器人按Xi升序排好序,令f[x]代表x~n的集合数,当第x个机器人不激活时,那么就是f[x+1];当第x个机器人被激活时,那么就是f[y],y代表离x最近的不被x影响(包括间接)的机器人。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MD=998244353;
const int N=2e5+5;
pair<int,int> p[N];
stack<pair<int,int> > st;
int f[N];
int main() {
    //freopen("in.txt","r",stdin);
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        scanf("%d%d",&p[i].first,&p[i].second);
    }
    sort(p+1,p+n+1);
    f[n+1]=1;
    for(int i=n;i>=1;i--) {
        int t=p[i].first+p[i].second,nex=i+1;
        while(!st.empty()&&t>p[st.top().first].first) {
            nex=st.top().second;
            st.pop();
        }
        st.push({i,nex});
        f[i]=(f[i+1]+f[nex])%MD;
    }
    printf("%d
",f[1]);
    return 0;
}
F.cpp

相关推荐