对于一个由0…n的所有数按升序组成的序列,我们要进行一些筛选,每次我们取当前所有数字中从小到大的第奇数位个的数,并将其丢弃。重复这一过程直到最后剩下一个数。请求出最后剩下的数字。
让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:域名注册、网页空间、营销软件、网站建设、涿鹿网站维护、网站推广。
输入描述:
每组数据一行一个数字,为题目中的n(n小于等于1000)。
输出描述:
一行输出最后剩下的数字。
输入例子:
500
输出例子:
255
方法一:常规解法,将数组不断更新,每一次去除奇位数的元素,直至数组的长度为1,输出即可。
算法复杂度:
T(n) = n + n/2 + n/4 +…1 = 2^n-1
故为O(2^n)
时间复杂度:
O(n)
代码:(偷个懒写个python版)
n = int(input())
lis = [i for i in range(0,n+1)]
while len(lis)!=1:
lis = [i for i in lis if (lis.index(i)+1)%2==0]
print(lis)
方法二:利用二进制巧妙解法
思路:
我们发现,每一次删除的元素都是对应下标位置的二进制最右端为0的元素,列如0(二进制为0),2(二进制为10),4(二进制为100)。剩余的元素例如1(01),3(11),5(101)在下一次的变换中对应的二进制下标为原二进制下标左移一位之后的1(1),3(10),5(10)之后继续删除对应下标的二进制数的最右端为0的元素。所以最后剩下的元素,一定是从右往左数二进制数中含1最多的元素,因为每一次删除移位后最右端都为1,会被一直保留下来
算法复杂度:
O(n)
空间复杂度:
O(1)
#includeusing namespace std;
int main(){int n;
cin>>n;
int x = 1;
while( x<= n )
x = x*2 +1;
cout<< (x>>1)<< endl;
}
方法三:数学公式法
分析可知,每一次减少一半的数据,经过long(n)(向下取整)次减少到只有一个数。那么只有2^floor(log(n)) 或者 2^floor(log(n))-1 能够经过long(n)次的向下取整之后得到1.因为在第一次删除时,已经去除所有的偶数,因此排除2log(n))。所以这个数为2log(n))-1
算法复杂度:
时间复杂度:O(1)
空间复杂度:O(1)
#includeusing namespace std;
int main(){int n;
cin>>n;
cout<<(int)pow(2,floor(log2(n)))-1<
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
分享标题:美团2016招聘笔试:奇数位丢弃-创新互联
标题URL:http://lswzjz.com/article/ddgdho.html