【递归】二进制字符串中的第K位

题目描述

给你两个正整数 n 和 k,二进制字符串 Sn 的形成规则如下:

  1. S1 = "0"
  2. 当 i > 1 时,Si = Si-1 + "1" + reverse(invert(Si-1))

其中 + 表示串联操作,reverse(x) 返回反转 x 后得到的字符串,而 invert(x) 则会翻转 x 中的每一位(0 变为 1,而 1 变为 0)。

例如,符合上述描述的序列的前 4 个字符串依次是:

S1 = "0"

S2 = "011"

S3 = "0111001"

S4 = "011100110110001"

请你返回 Sn 的 第 k 位字符 ,题目数据保证 k 一定在 Sn 长度范围以内。

例如输入:n = 3, k = 1,会输出:"0"。因为S3 为 "0111001",其第 1 位为 "0" 。

输入格式

第一行2个正整数:N K。N 范围[2, 30];

输出格式

1或0

输入/输出例子1

输入:

4 11

输出:

1

解题思路

这题的思路非常巧妙,通过观察我们知道二进制字符串Sn中间位都是1,左右两边是取反后并对称。所以,如果某一位处在后半段,我们可以找到前半段对应数位取反即可求到答案。这样我们可以把问题规模变小,当字符串长度为1或者是要求的数位处于S的中间位时我们就可以得到答案,然后结束。

因此我们可以定义递归函数,有三个组成要素,一个是字符串长度l,一个是我们要求的位k,还有一个是是否进行了取反操作rv,rv=1表示做了取反,rv=0表示没有取反。对于两个结束条件的返回值,先讨论通过若干次递归,问题规模变小,使得l=1的情况,对于这种情况如果没有取反操作的,我们观察S1可知,返回0(此时rv也是为0)。如果是后半段往前找的,就要取反,函数传的参数rv=1,返回1。归纳起来就是,如果长度为1时,返回rv。再看要求的数位处于S的中间位的情况,如果k在原字符串中本来就是处于前半段的,且折半后k在中间位就返回1。如果k在原字符串中本来就是处于后半段的,将其对应到前半段的位置l-k+1,且折半后在中间位就返回0(此时要取反)。所以返回的应该是1-rv。如果没达到结束条件,就进行折半和比较,直到到达结束条件为止。

AC代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n,k;
int dg(int l,int k,int rv){
	if(l==1) return rv;
	int m=(l+1)/2;
	if(m==k) return 1-rv;
	if(m<k) dg(l/2,l-k+1,1-rv);
	else dg(l/2,k,rv);
}
int main(){
	cin>>n>>k;
	int ln=0;
	for(int i=1;i<=n;i++) ln=ln*2+1;
	cout<<dg(ln,k,0);
	return 0;
}
相关推荐
徐小夕@趣谈前端3 分钟前
Web文档的“Office时刻“:jitword共建版2.0发布!让浏览器变成本地生产力
前端·数据结构·vue.js·算法·开源·编辑器·es6
问好眼7 分钟前
【信息学奥赛一本通】1275:【例9.19】乘积最大
c++·算法·动态规划·信息学奥赛
coder攻城狮22 分钟前
VTK系列1:在屏幕绘制多边形
c++·3d
Daydream.V25 分钟前
逻辑回归实例问题解决(LogisticRegression)
算法·机器学习·逻辑回归
代码无bug抓狂人25 分钟前
C语言之表达式括号匹配
c语言·开发语言·算法
不穿格子的程序员33 分钟前
从零开始写算法——普通数组篇:缺失的第一个正数
算法·leetcode·哈希算法
Nebula_g40 分钟前
线程进阶: 无人机自动防空平台开发教程(更新)
java·开发语言·数据结构·学习·算法·无人机
HAPPY酷1 小时前
构造与析构:C++ 中对象的温柔生灭
java·jvm·c++
又见野草1 小时前
C++类和对象(下)
开发语言·c++
rit84324991 小时前
基于MATLAB的环境障碍模型构建与蚁群算法路径规划实现
开发语言·算法·matlab