2021春季个人赛-8 补题

G.Magical Indices

题意: 统计一个数组 a a a的元素 x x x满足:
1.1 < x < n 1.1<x<n 1.1<x<n
2. a y ≤ a x 2.a_y\le a_x 2.ayax对任意的 1 ≤ y < x 1 \le y < x 1y<x
3. a x ≤ a z 3.a_x \le a_z 3.axaz对任意的 x < z ≤ n x<z\le n x<zn
分析: O ( n ) O(n) O(n)找出每个下标对应前面所有数的最大值和后面所有数的最小值,最后扫一遍即可。

代码:

#include<stdio.h>
#include<algorithm>
using namespace std;
const int N=1e6+5;
int t,n,a[N],pre[N],suf[N];
int main(){
    
    
    scanf("%d",&t);
    while(t--){
    
    
        scanf("%d",&n);
        for(int i=0;i<n;i++) scanf("%d",&a[i]);
        int res=0;
        pre[0]=a[0],suf[n-1]=a[n-1];
        for(int i=1;i<n;i++) pre[i]=max(pre[i-1],a[i]);
        for(int i=n-2;i>=0;i--) suf[i]=min(suf[i+1],a[i]);
        for(int i=1;i<n-1;i++){
    
    
            if(a[i]>=pre[i]&&a[i]<=suf[i]) res++;
        }
        printf("%d\n",res);
    }
}

J.The Hell Boy

题意: 给定一个长度为 n n n的数组 a a a,计算所有子数组的乘积之和
分析:
展开式 1 1 1 ( x + 1 ) ( y + 1 ) = x y + x + y + 1 (x+1)(y+1)=xy+x+y+1 (x+1)(y+1)=xy+x+y+1
展开式 2 2 2 ( x + 1 ) ( y + 1 ) ( z + 1 ) = x y z + x y + y z + x z + x + y + z + 1 (x+1)(y+1)(z+1)=xyz+xy+yz+xz+x+y+z+1 (x+1)(y+1)(z+1)=xyz+xy+yz+xz+x+y+z+1
根据上面两个式子推得,所有子集的乘积和为
( a 1 + 1 ) ( a 2 + 1 ) ⋯ ( a n + 1 ) − 1 (a_1+1)(a_2+1)\cdots(a_n+1)-1 (a1+1)(a2+1)(an+1)1

代码:

#include<stdio.h>
const int mod=1e9+7;
int t,n;
int main(){
    
    
    scanf("%d",&t);
    while(t--){
    
    
        long long res=0;
        scanf("%d",&n);
        for(int i=0,x;i<n;i++){
    
    
            scanf("%d",&x);
            res=(res+res*x+x)%mod;
        }
        printf("%lld\n",res);
    }
}

K.Palindromes Building

题意: 给定一个长度为 n n n的字符串,求它的所有回文串(任意排列)
分析: 如果有两个字母出现次数为奇数,那么不可能组成回文,输出0。其他情况就把这个串的长度除 2 2 2,分析一半的排列即可。
所有字母的排列数是 n 2 ! \frac{n}{2}! 2n!,但是会有重复的字母,所以要除每个字母的阶乘。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=15;
int t,n,x[127],jc[10];
char a[N];
int main(){
    
    
    cin>>t;
    jc[0]=1;
    for(int i=1;i<=10;i++) jc[i]=i*jc[i-1];
    while(t--){
    
    
        memset(x,0,sizeof x);
        int flag=0;
        cin>>n>>a;
        for(int i=0;i<n;i++) x[a[i]]++;
        for(int i='a';i<='z';i++){
    
    
            if(x[i]!=0&&x[i]%2==1) flag++;
            if(flag==2) break;
            x[i]/=2;
        }
        if(flag==2) cout<<0<<endl;
        else{
    
    
            n/=2;
            int res=jc[n];
            for(int i='a';i<='z';i++){
    
    
                if(x[i]!=0) res/=jc[x[i]];
            }
            cout<<res<<endl;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/messywind/article/details/115047391