CSU - 2055 Wells‘s Lottery

本文介绍了一个有趣的算法问题:如何通过最小限度地修改手中的彩票号码来确保没有两个号码通过位或运算能达到特定目标值。文章提供了一种解决策略,即分析每个数字的每一位(bit)对最终答案的贡献,并输出最小的修改次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

As is known to all, Wells is impoverished.
When God heard that, God decide to help the poor Wells from terrible condition.
One day Wells met God in dream, God gave Wells a secret number which will bought Wells a great fortune and gifted Wells an ablility of transforming two lottery tickets x, y into a lottery ticket z (meet the condition that z==x or y).

Wells realized that the number must be the result of lottery, which would be worth ¥5,000,000! Wells was very excited, and can't help sharing this thought. The secret number is X, and Wells has purchase N lottery tickets a1,a2,a3....aNa1,a2,a3....aN but has not received them yet. And if lucky enough, Wells could pick some numbers of them satisfy that b1orb2orb3....orbk=Xb1orb2orb3....orbk=X, k is the amount of picked numbers.

How ever the owner of the lottery shop called SDJ, who decided to modify the lottery tickets and made Wells lost his fortune. In order to save energy to modify the lottery tickets, SDJ want to know the minimum amount of modification of lottery tickets.

Input

The input only contains one line.
First line contains two positive integers N (N<=105)(N<=105),X (X<=109)(X<=109) ,N means as described above Second line contains N number a1,a2...aN(0<=ai<=109),aia1,a2...aN(0<=ai<=109),ai means the number on i-th lottery tickets.

Output

Output a line only contains minimum amount of modification of lottery tickets.

Sample Input

3 7 
4 2 1

Sample Output

1

Hint

It will be accepted after modifying any number.
The "or" in this problem means the bitwise or , for exmple , 0 or 0 = 0 ,0 or 1 = 1 , 1 or 1 = 1 , 3 or 5 =7.

Source

Author

Wells

题意:问最少改变多少个数,使任意数之间或运算都不能得到要求的数。

思路:考虑数字的每一个bit位,对于ai | X ==X 的说明对答案有贡献,把ai所有不为0的bit位的贡献+1即可 最后输出X所有为1的bit位的贡献得最小值 每个ai在判断有贡献后将1-30个bit位都for一遍计算贡献.

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<iostream>
using namespace std;
int n, x,m;
int cnt[35];
int main()
{
	while (~scanf("%d%d", &n, &x))
	{
		memset(cnt, 0, sizeof(cnt));
		int min = (1 << 30);
		
		for (int i = 0; i < n; i++)
		{
			scanf("%d", &m);
			if ((m | x) == x)
			{
				for (int j = 0; (1 << j) <= m; j++)
				{
					if ((1 << j)&m)
						cnt[j]++;
				}
			}
		}
		for (int i = 0; (1<<i) <=x; i++)
		{
			if (((1 << i)&x))
				min = min > cnt[i] ? cnt[i] : min;
		}
		printf("%d\n", min);

	}

	return 0;
}

转载于:https://www.cnblogs.com/csu-lmw/p/9124461.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值