P1 : Lucky Substrings
-
aabcd
Sample Output
-
a aa aab aabc ab abc b bc bcd c cd d
Description
A string s is LUCKY if and only if the number of different characters in s is a fibonacci number. Given a string consisting of only lower case letters, output all its lucky non-empty substrings in lexicographical order. Same substrings should be printed once.
Input
A string consisting no more than 100 lower case letters.
Output
Output the lucky substrings in lexicographical order, one per line. Same substrings should be printed once.
题意:给你一个串,让你按字典序输出所有的lucky子串。
思路一:暴力枚举子串,直接统计。时间复杂度O(n^3)。
思路二:设置dp[i][j]表示str.(i, j)里面不同字符的个数。先预处理子串中不同字符个数(感觉麻烦的话直接用状压记录),然后枚举子串,时间复杂度O(n^2)。
思路一:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <string>
#define INF 1000000
#define eps 1e-8
#define MAXN (10000+10)
#define MAXM (2000000+10)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while((a)--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
#define PI acos(-1.0)
#pragma comment(linker, "/STACK:102400000,102400000")
#define fi first
#define se second
using namespace std;
typedef pair<int, int> pii;
string G[MAXN];
string str, cstr;
map<char, bool> fp;
map<string, bool> tp;
int cnt;
bool judge(int s, int t)
{
fp.clear(); int sum = 0;
for(int i = s; i <= t; i++)
{
if(!fp[str[i]]) sum++;
fp[str[i]] = true;
}
G[cnt] = str.substr(s, t-s+1);
return sum == 1 || sum == 2 || sum == 3 || sum == 5 || sum == 8 || sum == 13 || sum == 21;
}
int main()
{
while(cin >> str)
{
int len = str.size(); cnt = 0; tp.clear();
for(int i = 0; i < len; i++)
for(int j = i; j < len; j++)
if(judge(i, j) && !tp[G[cnt]]) {tp[G[cnt]] = true; cnt++;}
sort(G, G+cnt);
for(int i = 0; i < cnt; i++) cout << G[i] << endl;
}
return 0;
}
思路二:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <string>
#define INF 1000000
#define eps 1e-8
#define MAXN (10000+10)
#define MAXM (2000000+10)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while((a)--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
#define PI acos(-1.0)
#pragma comment(linker, "/STACK:102400000,102400000")
#define fi first
#define se second
using namespace std;
typedef pair<int, int> pii;
string G[MAXN];
string str, cstr;
map<char, bool> fp;
map<string, bool> tp;
int cnt;
int dp[110][110];
bool State[1<<26];
bool judge(int sum){
return sum == 1 || sum == 2 || sum == 3 || sum == 5 || sum == 8 || sum == 13 || sum == 21;
}
int main()
{
while(cin >> str)
{
int len = str.size(); cnt = 0; tp.clear();
for(int i = 0; i < len; i++)
{
for(int j = 0; j < 26; j++) State[1<<j] = false;
for(int j = i; j < len; j++)
{
if(i == j) {dp[i][j] = 1; State[1<<(str[i]-'a')] = true;}
else
{
int val = str[j] - 'a';
dp[i][j] = dp[i][j-1] + (State[1<<val] ? 0 : 1);
State[1<<val] = true;
}
}
}
for(int i = 0; i < len; i++)
for(int j = i; j < len; j++)
if(judge(dp[i][j]) && !tp[str.substr(i, j-i+1)]) {G[cnt] = str.substr(i, j-i+1); tp[G[cnt]] = true; cnt++;}
sort(G, G+cnt);
for(int i = 0; i < cnt; i++) cout << G[i] << endl;
}
return 0;
}