题目链接
https://codeforces.com/contest/1694/problem/B
题意简述
样例
点击查看样例
分析
对于以 \(01\)结尾的串,如 \(a_1\ a_2\ a_3\ ...\ 0 \ 1\)
如果 \(0\) 的前一位是 \(1\) ,可以把 \(101\)缩为 \(01\)
如果 \(0\) 的前一位是 \(0\) ,可以把 \(001\)缩为 \(01\)
继续看 \(0\) 的前面的数字 ,循环往复,无论前面是多少,总能缩成 \(01\)
也就是不管 \(01\)的前面是 \(1\) 还是 \(0\) ,都能一直缩下去,最后变成 \(1\)
而对于以 \(10\) 结尾的串,同样拥有这个性质 , 只不过最后缩成的是 \(1\)
那么我们从前往后遍历这个字符串,
如果当前的字符跟他上一个相比不相同的话(即 \(10\) 或 \(01\))
说明只要以当前字符的下标 \(i\) 结尾的串都能缩成长度为 \(1\) 的串,而以 \(i\) 结尾的串 有 \(i+1\) 个子串( \(l=0\sim i,r=i\)).
如果当前的字符跟他上一个是同一个字符,那么以 \(i\) 结尾的串不可能缩成长度是 \(1\) 的,只能 \(i\)单独一个字符.
代码
点击查看代码
#include<stdio.h>
#include<iostream>
#include<cstdlib>
#include<string.h>
#include<algorithm>
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int main()
{
//freopen("uva.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
string s;
cin>>s;
LL cnt=1;
int len=s.length();
for(int i=1;i<len;i++)
{
if(s[i]!=s[i-1])
{
cnt+=(i-0+1);
}else cnt++;
}
printf("%lld\n",cnt);
}
return 0;
}