问题 I: 反对称串
时间限制: 5 Sec 内存限制: 16 MB提交: 115 解决: 28
[ 提交][ 状态][ 讨论版]
题目描述
有一个字符串只有0和1组成,对于某个子串,如果将0和1互换并且倒过来与原子串相同,则认为该子串是"反对称"的.给出一个长度为N的字符串,那么有多少个子串是"反对称"的?
输入
第一行一个正整数N(0<=N<=10000).
第二行包括一个长度为N的01串.
输出
输出"反对称"子串的个数.
样例输入
8
11001011
样例输出
7
提示
这7个"反对称"子串分别是001011,0101,1100出现一次,01和10都出现两次,共7个.
首先来看怎样才能满足反对称字串(即题目要求):如果将0和1互换并且倒过来与原子串相同,则认为该子串是"反对称"的。
咱先来考略字串长度的奇偶问题,如果是奇数,左右对称后,必然中间会留下一个数字,这个数字经0和1互换后,必然与原先不同,所以不必考虑奇数长度的字串(即满足条件的字串长度必然是偶数)。
解法一:枚举,枚举长度。
解法二:每一个满足条件的长度为n的子串(n>=4),将最左端和最右端字符去掉后得到n-2长度的字串必然也是满足条件的。即这个长度为n的子串的中心两个字符组成的子串必然也是符合条件的。所以可以从左向右搜长度为2的子串是否满足条件,如果满足则以这个子串为中心搜长度为4,6,8……直到条件不满足停止。
while(cin>>n){scanf("%s",b);
for(int i=1;i<=n;i++)
a[i]=b[i-1]-'0';
int sum=0;
for(int i=1;i<n;i++){
int pd=1,l=0;
while(pd){
if(a[i-l]^a[i+1+l])
{sum++;}
else
{pd=0;}
if(i-1-l>0&&i+2+l<=n)
l++;
else
pd=0;
}
}
cout<<sum<<endl;
}