我們把一個好的字符串的定義爲,如果合併了所有連續的相等字符,得到的
字符串是迴文。
例如,“aabbbaa”是好的字符串,因爲合併後的步驟將變成“aba”。
給定一個字符串,必須找到兩個值:
偶數長度的好的子串數;
奇數長度的好的子串數。
★數據輸入
輸入的第一行包含一個長度爲 n 的單一字符串
字符串的每個字符將是’a’或’b’。
字符長度 n
30 % 的數據 1 <= n <= 1000
100 % 的數據 1 <= n <= 100000
★數據輸出
第一行輸出偶數長度的好的子串數,奇數長度的好的子串數,以空格隔開
輸入示例 輸出示例
bb 1 2
輸入示例 輸出示例
baab 2 4
輸入示例 輸出示例
babb 2 5
★HINT 一個字符串是迴文,當且僅當把這個字符串翻轉後,還和原串一致。
比如“aba”、“abba”是迴文串,而“abc”,“abab”就不是。
觀察可知,其實最終的好序列必定是
abababababababab…
或者
babababbabab…
中的一個,並且,去重後的序列長度肯定爲奇數長度。
所以只要一個原串的首尾相同,就意味着它去重後一定是迴文串,因此,我們只需要統計一下有多少個’a’和多少個’b’就能算出有多少個好序列。假設有p個’a’,有q個’b’,則可以組成的好的序列有:
++(p+q)
至於原串是奇數還是偶數則要看起始下標和末尾下標的情況了
例如:
a b a a b a b a
對應下標:
1 2 3 4 5 6 7 8
那麼由第一個a到第二個a之間的字符所組成的字符串是 aba 長度爲(3-1)+1=3爲奇數
其實可以看到,因爲要把兩個端點算進去,所以這裏 奇數下標-奇數下標 得到的是奇數長度的串,同樣偶數下標-偶數下標 得到的數奇數長度的串,而偶數下標-奇數下標 和 奇數下標-偶數下標 都得到偶數長度的串,因此,奇數下標的a搭配偶數下標的a和奇數下標的b搭配偶數下標的b就得到了所求的字符串長度爲偶數的數量
代碼:
#pragma warning(disable:4996)
#include <stdio.h>
#include<string.h>
typedef long long ll;
typedef unsigned long long ull;
#define e 2.718281828459
#pragma warning(disable:4996)
#define sf scanf
#define pf printf
#define sf2d(x,y) scanf("%d %d",&(x),&(y))
#define sfd(x) scanf("%d",&x)
#define sff(p) scanf("%lf",&p)
#define pfd(x) printf("%d\n",x)
#define mset(x,b) memset((x),b,sizeof(x))
int main(void) {
char ch;
int suma = 0, sumb = 0;//ab總個數
int pra=0, prb=0;//奇數位置
int evena=0, evenb=0;//偶數位置
int cnt = 0;
while (ch = getchar(), (ch=='a'||ch=='b')) {
cnt++;
if (ch == 'a') {
suma++;//統計a的個數
if (cnt & 1)
pra++;//奇數位置的a的個數
else
evena++;//偶數位置的a的個數
}
else {
sumb++;
if (cnt & 1)
prb++;
else
evenb++;
}
}
int presum = suma + sumb + (pra - 1)*pra / 2 + evena * (evena - 1) / 2 + prb * (prb - 1) / 2 + evenb * (evenb - 1) / 2;//奇數長度的串,組合數
int evensum = pra * evena + prb * evenb;//偶數長度的串
pf("%d %d\n", evensum, presum);
return 0;
}