Codeforces Round #656 (Div. 3) D. a-Good String ###K ###K//K
题目链接:https://codeforces.ml/contest/1385/problem/D
题意:一个字符串如果长度为1 并且为'a' 那么就是 a -good 字符串,
当长度大于1时, 需要满足 将总区间划分成一半, 其中一半全是a,另一半必须为b-good 字符串 以此类推
思路: 直接考虑暴力搜索 每次分裂成两个一半的区间 分解成logn 层, 每一层的走的总长度都为n 总的复杂度为o(nlogn)
如 16 分为 2^3 和2^3 每个2^3 又分成2个 2^2
要注意的地方是 需要多一个参数来判断这是个左区间还是个右区间 n==1的时候特判一下, 区间长度等于1的时候在判一下隔壁区间的
然后特别要注意的就是区间的端点的判断,最好从长度入手和上一个区间的端点写,这样好写也不会出错
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ull unsigned long long 5 const int maxn =2e5+10; 6 #define pb push_back 7 char s[maxn]; 8 9 10 int ans=1e9; 11 void dfs(int l,int r,int num,int sum,int f) 12 { 13 for(int i=l;i<=r;i++) 14 { 15 char d=('a'+num); 16 if(d!=s[i]) 17 sum++; 18 } 19 if(l==r) 20 { 21 if(f) 22 { 23 char d=('a'+num+1); 24 if(s[r-1]==d) 25 ans=min(ans,sum); 26 else 27 ans=min(ans,sum+1); 28 } 29 else 30 { 31 char d=('a'+num+1); 32 if(s[r+1]==d) 33 ans=min(ans,sum); 34 else 35 ans=min(ans,sum+1); 36 } 37 //cout<<ans<<'\n'; 38 return; 39 } 40 int len=r-l+1; 41 if(f==0) 42 { 43 dfs(r+len/2+1,r+len/2+len/2,num+1,sum,1); 44 dfs(r+1,r+len/2,num+1,sum,0); 45 } 46 if(f==1) 47 { 48 dfs(l-len/2,l-1,num+1,sum,1); 49 dfs(l-len/2-len/2,l-len/2-1,num+1,sum,0); 50 } 51 52 } 53 54 55 int main() 56 { 57 ios::sync_with_stdio(false); 58 cin.tie(0); 59 int t; 60 cin>>t; 61 while(t--) 62 { 63 int n; 64 cin>>n; 65 cin>>(s+1); 66 if(n==1) 67 { 68 if(s[1]=='a') 69 { 70 cout<<0<<'\n'; 71 } 72 else 73 cout<<1<<'\n'; 74 continue; 75 } 76 ans=1e9; 77 int mid=(1+n)/2; 78 dfs(1,mid,0,0,0); 79 if(n!=1) 80 dfs(mid+1,n,0,0,1); 81 cout<<ans<<'\n'; 82 83 } 84 85 86 87 88 89 90 }