牛客练习赛45

A-QAQ

题意:给一个长度为 N 的字符串S, 求S中不含相邻字符且长度为的"QAQ"子序列个数.
题解:把'Q'的个数做前缀和后缀和处理,a[] 存储'Q'个数的前缀和,b[]存储'Q'个数后缀和,如果第i个字符是'A',那么这时的个数为a[i-2] * b[i+2],枚举每一个'A',求和即可.

#include <bits/stdc++.h>
using namespace std;
const int N=5e3+5;
char s[N];
int a[N],b[N];
typedef long long ll;
int main(){
    scanf("%s",s+1);
    int n=strlen(s+1);
    for(int i=1;i<=n;i++){
        if(s[i]=='Q') a[i]=a[i-1]+1;
        else a[i]=a[i-1];
        if(s[n-i+1]=='Q') b[n-i+1]=b[n-i+2]+1;
        else b[n-i+1]=b[n-i+2]; 
    }
    ll ans=0;
    for(int i=3;i<=n-2;i++){
        if(s[i]=='A') ans+=1ll*a[i-2]*b[i+2];
    }
    cout<<ans<<endl;
    return 0;
}
tips:实际上可以不用预先计算前缀和,可以边处理边计算前缀和.
#include <bits/stdc++.h>
using namespace std;
const int N=5e3+5;
char s[N];
int b[N];
typedef long long ll;
int main(){
    scanf("%s",s+1);
    int n=strlen(s+1);
    for(int i=1;i<=n;i++){
        if(s[n-i+1]=='Q') b[n-i+1]=b[n-i+2]+1;
        else b[n-i+1]=b[n-i+2]; 
    }
    ll ans=0;
    int cnt=(s[1]=='Q')+(s[2]=='Q');
    for(int i=3;i<=n-2;i++){
        if(s[i]=='A') ans+=1ll*(s[i-1]=='Q'?cnt-1:cnt)*b[i+2];
        cnt+=s[i]=='Q';
    }
    cout<<ans<<endl;
    return 0;
}

C-Buy Fruits

题意:给你一组n个数,是[0,n-1]的一个排列,记为a,让你输出一组n个数,也是[0,n-1]的一个排列,记为b.使得每一个a[i]+b[i]值在[1,n-1]内,且只有某一个数重复一次.
题解:瞎搞找了个规律. 如果n为奇数(除了1,),输出 -1(1输出 0),如果n为偶数,b[0]=1,b[n/2]=0,b[i]=n-i-i,b[n-i+1]=(n+1)-a[i].如n=4, b[] =1, 2, 0, 3.

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N];
int vis[N];
int main(){
    int n;
    cin>>n;
    if(n==1){
        printf("0\n");
        return 0;
    }
    if(n&1){
        puts("-1");
        return 0;
    }
    else{
        a[0]=1;
        for(int i=1;i<=n/2;i++){
            if(i*2==n) a[i]=0;
            else{
                a[i]=n-i-i;
                a[n-i]=(n+1)-a[i];
            }
        }
    }
    for(int i=0;i<n;i++){
        printf("%d%c",a[i],i==n-1?'\n':' ');
    }
    return 0;
    
}

猜你喜欢

转载自www.cnblogs.com/-yjun/p/10807014.html