給定字串s,判定s是否存在子串s』滿足"aa…abb…bcc…c"的形式。其中abc為連續的三個字母,且a,b,c的數量相同。
原題目中數量相等的連續n(n>3)個字母也是可行的,而實際上當n>3時一定包含有n=3的情況。比如"abcd"就包含有"abc"和"bcd"兩個合法子串。
最基本的思路為對s的每乙個子串進行判定是否滿足要求。列舉子串的起點、終點以及檢查是否合法。
假設s的長度為n,則時間複雜度為o(n^3)。
for i =
0..n-
1 for j =
0..n-
1check
(s[i.
.j])
end for
end for
這樣的做法對於n稍大的資料來說就會超過時限。
進一步考慮,由於合法子串中相同的字母總是連續的,我們不妨用(c,n)來表示一串連續相同的字母,比如"aaa"表示(a,3),"bb"表示為(b,2)。
我們將整個字串s用(c,n)表示,得到的序列。其中我們合法的子串也可以表示為。
則演算法改變為在序列中判定是否存在連續的3個元素滿足c[i],c[i+1],c[i+2]連續且n[i] == n[i+1] == n[i+2]。
預處理時間為o(n),得到的序列長度最大為n,所以整體的時間複雜度降低為o(n)。
for i =1.
. t-
2 if (c[i]+1
== c[i+
1] and c[i+1]
+1== c[i+2]
) and (n[i]
== n[i+1]
== n[i+2]
) return true
end if
end for
然而實際執行會發現,這個演算法是不正確的。比如:「aaaabbccc」,其對應的序列為,根據我們上面的演算法並不能找到合法子串。但實際上存在合法子串"aabbcc"。
很顯然,問題出在我們對於n[i],n[i+1],n[i+2]的判定上。通過上面的反例我們可以發現,在子串中n[i],n[i+2]的值其實是可以變動的,唯一固定的是n[i+1]的值。當n[i]>n[i+1]時,我們只要刪去前面的若干個字母,就能夠使得n[i]==n[i+1]。同理對於n[i+2]>n[i+1]時,我們刪去後面的字母。因此只要有n[i]>=n[i+1],n[i+2]>=n[i+1],就一定能夠通過變換使得n[i] == n[i+1] == n[i+2]。
改正後我們的演算法**為:
for i =1.
. t-
2 if (c[i]+1
== c[i+
1] and c[i+1]
+1== c[i+2]
) and (n[i]
>= n[i+
1] and n[i+1]
<= n[i+2]
) return true
end if
end for
在實際的比賽中,該題目的通過率僅為26%。
但根據賽後的統計結果,大部分的選手都使用了樸素的演算法通過了規模較小的資料點。在該題目上獲取了10~60不等的分數。
其中比較有意思的是有一位選手僅僅判定連續3個字母是否連續,也獲得了60的分數。
而分布在70~90分數段的程式,隨機抽取了若干樣本,發現大多數都是想到了正確演算法的。而導致他們丟分的主要原因則是多組資料產生的初始化問題。
#include
using namespace std;
#define ll long long
const
int mod =
1e9+7;
const
int maxn =
1e7+5;
const
double eps =
0.00000001
;const
int inf =
0x3f3f3f3f
;int c[maxn]
, m[maxn]
;bool solve()
m[cnt]++;
}for
(ll i =
1; i <= cnt -
1; i ++)if
(c[i -1]
+1== c[i]
&& c[i]+1
== c[i +1]
&& m[i -1]
>= m[i]
&& m[i]
<= m[i +1]
)return true;
return false;
}int
main()
return0;
}
hiho一下第143周
題目1 hiho密碼 時間限制 10000ms 單點時限 1000ms 記憶體限制 256mb 描述 小ho根據最近在密碼學課上學習到的知識,開發出了一款hiho密碼,這款密碼的秘鑰是這樣生成的 對於一種有n個字母的語言,選擇乙個長度為m的單詞 將組成這個單詞的所有字母按照順序不重複的寫出 即遇到相...
hiho 學習日記 hiho一下第二十八周 (堆)
堆的形狀是乙個完全二叉樹,對於最大堆任意根的權值大於左右孩子的權值,而最小堆的任意根的權值小於左右孩子的權值 這裡演示的是最大堆 當插入乙個值的時候,把這個值新增到堆尾中,然後向上調整 voidup int p heap p a void insert int a 刪除堆頂的值的時候,把堆尾的元素賦...
hiho一下 第197周 逆序單詞
時間限制 10000ms 單點時限 1000ms 記憶體限制 256mb 在英文中有很多逆序的單詞,比如dog和god,evil和live等等。現在給出乙份包含n個單詞的單詞表,其中每個單詞只出現一次,請你找出其中有多少對逆序單詞。第1行 1個整數,n,表示單詞數量。2 n 50,000。第2.n ...