题目网页链接: http://codeforces.com/gym/101745/problem/D
思路:首先可以确保能够成功染色的字符串都是结果串的子串,那么O(n^2)枚举子串之后dp转移即可。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 typedef long long ll; 5 const int mod=1e9+7; 6 const int maxn=1e5+10; 7 const int inf=0x3f3f3f3f; 8 const double eps=1e-14; 9 const double pi=acos(-1.0); 10 #define mem(s,v) memset(s,v,sizeof(s)) 11 #define pdd pair<double,double> 12 #define pii pair<int,int> 13 14 string s,ss; 15 set<string> se; 16 int dp[155][155]; 17 int n; 18 19 int judge(string ss){ 20 if(ss[0]!=s[0]) return 0; 21 memset(dp,0,sizeof(dp)); 22 dp[0][0]=1; 23 int m=ss.size(); 24 for(int i=0;i<n-1;++i){ 25 for(int j=0;j<m;++j){ 26 if(!dp[i][j]) continue; 27 if(s[i+1]==ss[(j+1)%m]) dp[i+1][(j+1)%m]=1; 28 if(s[i+1]==ss[0]) dp[i+1][0]=1; 29 } 30 if(dp[i][m-1]){ 31 for(int j=0;j<m;++j){ 32 if(s[i+1]==ss[j]) dp[i+1][j]=1; 33 } 34 } 35 } 36 return dp[n-1][m-1]; 37 } 38 39 int main(){ 40 cin>>s; 41 n=s.size(); 42 for(int i=0;i<n-1;++i){ 43 for(int j=i;j<n;++j){ 44 ss=s.substr(i,j-i+1); 45 if(judge(ss)) se.insert(ss); 46 } 47 } 48 for(auto it : se){ 49 cout<<it<<endl; 50 } 51 return 0; 52 }