【A】水题,预处理一下就可以了。

【B】构造,判断一下最大值和最小值的差是否>k,是的话无解,否者xjb构造就行了。

int n, k, a[111];

int main()
{
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        int mx = 0, mi = 200;
        for(int i = 1; i <= n; i++){
            scanf("%d",&a[i]);
            mx = max(mx, a[i]);
            mi = min(mi, a[i]);
        }
        if(mx-mi>k){
            puts("NO");
            continue;
        }
        printf("YES\n");
        for(int i = 1; i <= n; i++){
            int cc = 1;
            for(int j = 1; j <= a[i]; j++){
                printf("%d ",cc++);
                if(cc == k + 1) cc = 1;
            }
            printf("\n");
        }
    }
}

【C】不会,看了网上的题解。给了每个数的每一位的数字之和,要你构造原来的这个序列,满足递增的顺序并且满足最后一位最小。贪心的策略是:直接找比前一位大,并且最小的数。

const int maxn = 333;
int a[maxn],res[maxn],len,n;

void print(int t)
{
    for(int i = 1;  t > 0; i++){
        while(res[i] < 9 && t > 0) res[i]++, t--;
        len = max(len, i);
    }
    for(int i = len; i >= 1; i--) printf("%d",res[i]);
    printf("\n");
}

void solve(int t)
{
    if(t > 0) print(t);
    else{
        for(int i = 1; i <= len + 1; i++){
            if(t > 0){
                while(res[i] == 9) res[i] = 0, t += 9, i++;
                res[i]++,t--;
                if(i == len + 1) len++;
                print(t);
                break;
            }
            else
            {
                t += res[i], res[i] = 0;
            }
        }
    }
}
int main()
{
    while(scanf("%d",&n) != EOF)
    {
        a[0] = 0;
        for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
        len = 1;
        for(int i = 1; i <= n; i++){
            int t = a[i] - a[i-1];
            solve(t);
        }
    }
}

【E】给了一个字符串,要你求所有字串的一个比例之和,这个比例等于元音字母的个数除以字串长度。很容易想到,把这个串变成01串,维护一个前缀和。枚举字串的长度k,对于每一个k,答案等于Sigma(s[k]-s[0]+(s[k+1]-s[1])+...+(s[n]-s[n-k])),很容易发现维护前缀和之后,分子变成了sum[n]-sum[k-1]-sum[n-k]。然后O(1)的算出这个值。加上枚举长度,复杂度才O(len)。

const int maxn = 5e5+20;

char s[maxn];
int a[maxn];
LL sum[maxn];

int main()
{
    while(scanf("%s",s+1)!=EOF)
    {
        int len = strlen(s+1);
        for(int i = 1; i <= len; i++){
            if(s[i] == 'I' || s[i] == 'E' || s[i] == 'A' || s[i] == 'O' || s[i] == 'U' || s[i] == 'Y'){
                a[i] = 1;
            }
            else{
                a[i] = 0;
            }
        }
        memset(sum, 0, sizeof(sum));
        for(int i = 1; i <= len; i++){
            a[i] += a[i-1];
            sum[i] = sum[i-1] + a[i];
        }
        double ans = 0.0;
        for(int k = 1; k <= len; k++)
        {
            ans = ans + (double)(sum[len] - sum[k - 1] - sum[len - k]) / k*1.0;
        }
        printf("%.8f\n", ans);
    }
    return 0;
}