文章目录

1 题目

LUCKY STRING
时间限制 1000 ms 内存限制 32768 KB 代码长度限制 100 KB 判断程序 Standard (来自 小小)
题目描述
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.

输入描述:
a string consisting no more than 100 lower case letters.

输出描述:
output the lucky substrings in lexicographical order.one per line. Same substrings should be printed once.

输入例子:
aabcd

输出例子:
a
aa
aab
aabc
ab
abc
b
bc
bcd
c
cd
d

2 解析

2.1 题意

判断当前字符串的所有子串不同字母的个数是否是斐波那契数,如果是,则输出,否则,继续判断下一个子串。

2.2 思路

  • 打表,打印100以内的斐波那契数
  • 用set<char>实现去重统计字符串个数,
  • 每次判断当前子串的不同字母的个数是否是斐波那契数,如果是,则存入set<string>(是想按字典序排序的要求);如果是下一个斐波那契数,重新判断,存入set<string>(是想按字典序排序的要求);如果不是,继续判断下一个子串。
  • 最后输出结果。

3 参考代码

#include 
#include
#include

using std::cin; using std::cout;
using std::set; using std::string;
using std::endl;

int fib[] = {1,1,2,3,5,8,13,21,34,55,89};//打表
set<string> result;

int main()
{
string str;
cin >> str;
int n = str.length();
for(int i = 0; i < n; i++) {//遍历每个字符,确定子串的首字母
set<char> s;//统计子串中的每个不同字符的数目
int k = 1;
for (int j = i; j < n; j++) {//固定首字母,增加剩余的字母
s.insert(str[j]);
if (s.size() == fib[k]) {//如果是斐波那契数,继续递增字母数量
result.insert(str.substr(i, j - i + 1));//当前字符拼接从i开始长度为j-i+1的字符
} else if (s.size() == fib[k + 1]) {//如果是下一个斐波那契数
j--;//回头重新判断这个字符串(防止漏判)
k++;//斐波那契数更新为下一个斐波那契数
}
}
}

for (auto it = result.begin(); it != result.end(); it++) {
cout << *it << endl;
}

return 0;
}