问题描述
数据已于 2024 年 11 月 18 日加强
暗影大帝又双叒叕来搞破坏了。这次,他派出了 nn 个暗影护法,每个护法都携带了一面写着 00 或 11 的旗帜。这些旗帜连起来,就组成了一个长度为 nn 的二进制暗号串 SS。
皮皮虾 ERP 研究协会的专家们确信,暗影大帝的最终阴谋就藏在这个暗号串里。他们发现,每个连续的旗帜子集都对应着一个能量值,这个能量值可以通过将旗帜上的二进制数字串转换成十进制数得到。例如,如果旗帜子集是 "101",则对应的能量值就是 55。
为了阻止暗影大帝的阴谋,铠甲勇士们需要找到最小的、没有被使用的能量值。这个能量值代表着暗影大帝阴谋中缺失的关键环节,找到它就能瓦解暗影大帝的计划。
具体来说,定义 F(l,r)F(l,r) 为子串 S[l…r]S[l…r] 转换成的十进制能量值。现在,对于所有的 F(l,r)F(l,r),请你帮助铠甲勇士找出其中最小的、不存在的非负整数。
输入格式
第一行输入一个整数 nn (1≤N≤1051≤N≤105) ,表示暗号串的长度。
第二行输入一个长度为 NN 的二进制字符串 SS,表示暗号串。
输出格式
输出一个整数,表示最小的、不存在的非负整数能量值。
样例输入
3
101
样例输出
3
样例说明
子串 | 二进制 | 十进制 |
---|---|---|
S1,1S1,1 | 1 | 1 |
S1,2S1,2 | 10 | 2 |
S1,3S1,3 | 101 | 5 |
S2,2S2,2 | 0 | 0 |
S2,3S2,3 | 01 | 1 |
S3,3S3,3 | 1 | 1 |
未出现的最小非负整数为 3。
#include <iostream>
#include <string>
using namespace std;
int N;
string S;
int a[100000];//用于标记哪些十进制整数已经出现过,数组初始化为0,表示未出现过
int tran(string s)//函数作用,将二进制转换为十进制
{
int sum = 0;
for (int i = s.size() - 1; i >= 0; i--)
sum += (s[i] - '0') * 1 << (s.size() - 1 - i);//s[i] - '0':将字符 s[i] 转换为对应的数字(0 或 1;1 << (s.size() - 1 - i),计算当前位对应的 2 的幂次方
return sum;
}
int main()
{
cin >> N >> S;
for (int b = 1; b <= 16; b++)
for (int i = 0; i <= N - b; i++)
a[tran(S.substr(i, b))] = 1;//截取字符串 S 从位置 i 开始长度为 b 的子串
int i = 0;
while (a[i])//找到第一个a[i]为0的i;
i++;
cout << i;
return 0;
}
b为什么最大为16,对于某个特定的长度b,长度为b的子串的个数只有n+1-b个,要使所有n+1-b个数覆盖2^(b-1),所以b并不会太大