迴文子串問題

題面:

給定一個只含大寫AB的字符串,問這個字符串有多少個子串是Delicious的。

Delicious定義:對於一個字符串,我們認爲它是Delicious的當且僅當它的每一個字符都屬於一個大於1的迴文子串

輸入第一行一個正整數n,表示字符串長度,接下來一行,一個長度爲n只由大寫字母A、B構成的字符串

輸出僅一行,表示符合題目要求的子串的個數。

sample input:
5
AABBB

sample output:
6
(對於該樣例,符合條件的六個子串分別是:s1-s2,s1-s4,s1-s5,s3-s4,s3-s5,s4-s5)

數據組成

在這裏插入圖片描述

思路:

  • 測試的時候完全沒有懂這個題目在說什麼,所以最後隨緣寫了一個混了一個樣例分,當時的思路是先把所有迴文子串找出來再想辦法算總數,然後就繞進去了
  • 首先要理解他的樣例的意思,要求所有字符都屬於長度大於一併且完整包含在字符串的迴文子串中,也就是說如果出現了單個的與上個字符不相同的字符就肯定是錯的,比如AAB,AAAB
  • 首先利用公式計算出字符串所有子串的個數ans,然後對於不符合條件的子串進行計數。利用pos記錄上一次AB\BA的分界處,利用num記錄AB\BA個數。從頭到尾再從尾到頭遍歷,尋找交界位置,即不符合條件的子串。
  • 需要注意的是從頭到尾從尾到頭的兩次是爲了防止ABBB,AAAB情況的遺漏,但是這樣就減了兩次AB\BA,所以加上一個num
  • 由於n到達了五次方,所以使用long long 定義ans
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
 long long n;
 long long ans=0;
 scanf("%d",&n);
 string s;
 cin>>s;
 int pos=0;
 int num=0;
 int loss=0;
 ans=(n*(n-1))/2;
 for(int i=0;i<n-1;i++)
 {
  if(s[i]!=s[i+1])
  {
   loss+=(i+1-pos);
   pos=i+1;
   num++;
  }
 }
 pos=n-1;
 for(int i=n-1;i>0;i--)
 {
  if(s[i]!=s[i-1])
  {
   loss+=(pos-i+1);
   pos=i-1;
  }
 }
 ans=ans-loss+num;
 printf("%lld",ans);
 return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章