AtCoder Regular Contest 104

只看懂前两题。。。
B题:前缀和

// A T G C

// A <=> T
// C <=> G

#include<iostream>
using namespace std;

const int N = 5010;

int a[N], g[N], t[N], c[N];
int n;
char s[N];

int main(){
    cin >> n >> s + 1;
    
    for(int i = 1; i <= n; i ++){
        if(s[i] == 'A') a[i] ++;
        if(s[i] == 'G') g[i] ++;
        if(s[i] == 'T') t[i] ++;
        if(s[i] == 'C') c[i] ++;
    }
    
    for(int i = 1; i <= n; i ++){
        a[i] = a[i - 1] + a[i];
        g[i] = g[i - 1] + g[i];
        t[i] = t[i - 1] + t[i];
        c[i] = c[i - 1] + c[i];
    }
    
    int res = 0;
    
    for(int i = 1; i <= n; i ++)
        for(int j = i + 1; j <= n; j ++){
            int as = a[j] - a[i - 1], 
                ts = t[j] - t[i - 1],
                gs = g[j] - g[i - 1],
                cs = c[j] - c[i - 1];
            if(as == ts && gs == cs) res ++;
        }
    
    
    cout << res << endl;
    
    return 0;
}

也可以在扫区间的时候,直接求出个数

#include<iostream>
using namespace std;

const int N = 5010;

char s[N];
int n;

int main(){
    cin >> n >> s;
    
    int res = 0;
    
    for(int i = 0; i < n; i ++){
        int as, ts, gs, cs;
        as = ts = gs = cs = 0;
        for(int j = i; j < n; j ++){
            if(s[j] == 'A') as ++;
            if(s[j] == 'T') ts ++;
            if(s[j] == 'G') gs ++;
            if(s[j] == 'C') cs ++;
            
            if(as == ts && gs == cs) res ++;
        }
    }
    
    cout << res << endl;
    
    return 0;
}
原文地址:https://www.cnblogs.com/tomori/p/13765540.html