D. a-Good String

传送门

题意

一个字符串如果长度为1 并且为’a’ 那么就是 a -good 字符串,
当长度大于1时, 需要满足 : 将总区间划分成一半, 其中一半全是a,另一半必须为b-good 字符串 以此类推

分析

这道题的做法比较直观,不断将字符串分段,然后递归下去,主要思想为分治,时间复杂度为标准的nlogn

代码

用dfs,类似于归并排序的思想,统计出上半段符合当前深度的字母,下半段符合当前深度的字母,然后递归下去即可

好像没有合适的剪枝方法,我剪枝三次一直是WA2,后来直接暴力ac了2333

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
 
const int N = 131080;
int a[N];
 
 
int dfs(int l,int r,int d){
    if(r - l == 1){
        if((a[l] == d && a[r] == d + 1 )|| (a[l] == d + 1 && a[r] == d)) return 0;
        if(a[l] == d || a[l] == d + 1 || a[r] == d || a[r] == d + 1) return 1;
        return 2;
    }
    int m = (r + l - 1) / 2;
    int sum1 = 0,sum2 = 0;
    for(int i = l;i <= m;i++) if(a[i] == d) sum1++;
    for(int i = m + 1;i <= r;i++) if(a[i] == d) sum2++;
    int ans1 =(m - l + 1 - sum2) + dfs(l,m,d + 1);
    int ans2 =(m - l + 1 - sum1) + dfs(m + 1,r,d + 1);
    return min(ans1,ans2);
}
 
int main(){
    int T,n;
    cin >> T;
    while(T--){
        cin >> n;
        char str[N];
        cin >> (str + 1);
        for(int i = 1;i <= n;i++) a[i] = str[i] - 'a' + 1;
        if(n == 1){
            if(a[1] == 1)
                cout << 0 << endl;
            else
                cout << 1 << endl;
            continue;
        }
        cout << dfs(1,n,1) << endl;;
    }
    
}
 

猜你喜欢

转载自blog.csdn.net/tlyzxc/article/details/107430647