子序列的权值最小值

子序列的权值最小值

题目描述

给定一个长度为 n 的数组 a ,求数组所有非空子序列权值的最小值。

定义子序列 ai , aj , … , ak 的权值为 ai&aj&…&ak

其中 & 为二进制中的按位与

按位与的定义:链接:https://ac.nowcoder.com/acm/contest/49030/A

输入描述

第一行包含一个正整数 n(1≤n≤20) 代表数组长度。

第二行包含 n 个正整数 ai(1≤ai≤109) 代表数组中每个数的值。

输出描述

输出数组中所有飞控子序列权值的最小值。

示例1

输入

6
1 1 4 5 1 4

输出

0

备注

子序列不一定连续

题解

按位与的运算规律:

1&1=1
1&0=0
0&1=0
0&0=0

同 1 得 1有 0 得 0。即如果某位上的数为 0 ,与其他任何 n-1 个数按位与后,该位上的数仍为 0 ;所以除非参与运算的所有数在某位上全为 1 ,得到的结果在该位上才能为 1 。

想要得到最小值,需要每位上的数都是最小值,所以将序列中所有的数按位与,结果即为最小值。

证明:如果所有数在某位上都为 1 ,则挑出其中任意 k 个按位与后仍为 1 ,且是最小值,如果该位上的最小值可以是 0 ,则在该位上至少存在一个 0 ,与条件“所有数在该位上都为 1 ”相悖,所以 1 就是最小值;如果在某位上存在 0 ,则与其他 n-1 个数按位与后该为的结果仍为 0 ,且是最小值。

综上,将序列中所有的数按位与所得结果就是最小值。

代码

#include <iostream>
using namespace std;
const int N = 27;
int a[N];
int main(void)
{
	int n;
	cin >> n;
	for (int i = 1; i <= n; ++i) cin >> a[i];
	int ans = a[1];
	for (int i = 2; i <= n; ++i) ans &= a[i];
	cout << ans;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值