最大字符集

题目描述
Cubercsl 很喜欢 01 字符串,就像“她喜欢大海”,这一天他想送她一个由 01 字符串组成的集合。
他自然是希望这个集合越多样化越大越好。所以他希望这个集合满足以下条件。
每个字符串由 0 和 1 组成。
每个字符串长度在 1 到 n 之间,且两两长度不同。
集合中任何一个字符串都不是其他字符串的子串。
请你帮他找到满足他要求的最大的集合。
字符串 a 是 b 的子串当且仅当从 b 的头部和尾部删除一些字符(可以是零个或者所有)能得到的 a。

输入描述:
仅一行,包含一个整数 n(1 \leq n \leq 3001≤n≤300)。
输出描述:
第一行输出这个集合的大小 k。
接下来 k 行每行输出一个 01 字符串,表示这个集合的一个元素。
答案不唯一,任何符合要求链接:
输入
1
输出
1
1
输入
5
输出
4
00
110
1010
11111
思路:这一题属于构造题,主要是找规律,题目要求给定一个n,然后输出元素长度小于等于n的字符集,且相同长度的其中一种就可以。当给出1时,可以1或0;当为2时,有1,00或0,11;当为3时,00,010或11,010(如果还按照1,2那种分法也是两个1,00或0,11);为4时如果还按照第一个放一个1,或0,那只会有2种情况,那这就得不偿失了,所以,可以按照,00,010,0110,这样不会出现前面为后面的子串,且可以发现,在以后的n都对应有n-1个集合元素。这个集合元素在长度不相等时有一条规律,如下图。
00
010
0110
01110
011110

可以发现在中间插入一个1,那这个集合就是一个有规律得了,虽然相同长度有其他种情况,但其他种情况不能保证不会是后面得子串。

#include <bits/stdc++.h>
#define LL long long
using namespace std;
int n;
int main()
{
    cin >> n;
    if (n == 1)      //1 是一个特殊情况
    {
        cout << 1 << '\n';
        cout << 1 << '\n';
        return 0;
    }
    if (n == 2){
        cout << 2 << '\n';
        cout << 0 << '\n';
        cout << 11 << '\n';
        return 0;
    }
    if (n == 3){
        puts("2");
        puts("00");
        puts("111");        //这也可以是101
        return 0;
    }
    cout << n-1 << '\n';        //可以发现在3以后每一个n对应有n-1种情况,
    cout << "00\n";
    for (int i = 3; i <= n; ++i){
        cout << 0;
        for (int j = 1; j <= i-2; ++j) cout << 1;
        cout << 0;
        cout << '\n';
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_46687179/article/details/105605028
今日推荐