题解/算法 {C - Avoid K Palindrome 2}
@LINK: https://atcoder.jp/contests/abc363/tasks/abc363_c
;
这是个标准的算法 即有重复的全排列;
#看一个超时做法#
比如他长度是N
, 然后我们弄一个[0,1,2,...,9]
然后执行全排列std::next_permutation
每一次判定Check()
是否合法 然后累加答案;
可是他有个问题, 即会遇到重复的排列 你是需要去重的 (比如aab
你会得到aab, aab, aba, aba, baa, baa
), 于是就只能再用一个unordered_set< string>
去判重;
然而这样的话, 你的时间就是10! = 4e6
, 即4e6 * log(4e6)
这就超时了;
vector<int> Ind( N); std::iota( Ind.begin(), Ind.end(), 0);
string T = S;
unordered_set<string> US;
int ANS = 0;
do{
FOR_( i, 0, N-1){ T[i] = S[ Ind[i]];}
if( US.find( T) != US.end()){ continue;}
US.insert( T);
if( Check()){ ++ ANS;}
}while( std::next_permutation( Ind.begin(), Ind.end()));
cout<< ANS<< "\n";
正确的做法是: 其实你弄一个Ind
再用