Educational Codeforces Round 53 (Rated for Div. 2) A Diverse Substring
https://www.cnblogs.com/violet-acmer/p/10163375.html
题意:
给出串是多态的定义“长度为 n 的串 s ,当串 s 中所有字母出现的次数严格 ≤ n/2,就称此串是多态的”。
求某串 s 是否含有多态的字串,如果含有,输出"YES",并输出此串,反之,输出"NO"。
题解:
开局连 wa 五发,读错题意了,难受。
比赛时提交的代码是暴力过的,就是判断长度为 len 的字串是否为多态串,枚举所有可能。
用了树状数组稍加优化了一番,代码如下:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 #define mem(a,b) memset(a,b,sizeof(a)) 6 const int maxn=1e3+10; 7 8 int n; 9 char s[maxn]; 10 //'a' <- 0,'b' <- 1,依次类推 11 //bit[i][j] : 前j个字符字母i出现的次数 12 int bit[26][maxn]; 13 void Add(int t,int i) 14 { 15 while(t <= n) 16 { 17 bit[i][t]++; 18 t += (t&-t); 19 } 20 } 21 int Sum(int t,int i) 22 { 23 int res=0; 24 while(t > 0) 25 { 26 res += bit[i][t]; 27 t -= (t&-t); 28 } 29 return res; 30 } 31 bool isSat(int a,int b) 32 { 33 for(int i=0;i < 26;++i) 34 if(Sum(b,i)-Sum(a-1,i) > ((b-a+1)>>1)) 35 return false; 36 return true; 37 } 38 void Solve() 39 { 40 mem(bit,0); 41 for(int i=1;i <= n;++i) 42 Add(i,s[i]-'a'); 43 for(int len=2;len <= n;++len) 44 { 45 for(int i=1;i+len-1 <= n;++i) 46 { 47 int j=i+len-1; 48 if(isSat(i,j)) 49 { 50 printf("YES\n"); 51 for(int k=i;k <= j;++k) 52 printf("%c",s[k]); 53 printf("\n"); 54 return ; 55 } 56 } 57 } 58 printf("NO\n"); 59 } 60 int main() 61 { 62 scanf("%d%s",&n,s+1); 63 Solve(); 64 return 0; 65 }
然后,今天整理这道题的时候,突然想到,如果含有两个连续的不同字符,那这个子串肯定是多态的啊,so,写了个短短的代码。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 #define mem(a,b) memset(a,b,sizeof(a)) 6 const int maxn=1e3+10; 7 8 int n; 9 char s[maxn]; 10 11 void Solve() 12 { 13 for(int i=2;i <= n;++i) 14 { 15 if(s[i] != s[i-1]) 16 { 17 printf("YES\n"); 18 printf("%c%c\n",s[i-1],s[i]); 19 return ; 20 } 21 } 22 printf("NO\n"); 23 } 24 int main() 25 { 26 scanf("%d%s",&n,s+1); 27 Solve(); 28 return 0; 29 }