CF1694B Paranoid String#800(div.2)

题目链接

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;
}
posted @ 2022-09-18 16:09  LZH_03  阅读(33)  评论(0编辑  收藏  举报