看似简单实际很难的查找问题所有的m位(二进制)数中找出n个数,使得任意2个数至少有k位不同。对于给定的m,k(m
看似简单实际很难的查找问题
所有的m位(二进制)数中找出n个数,使得任意2个数至少有k位不同。
对于给定的m,k(m>=k)求n的最大值?
[解决办法]
感觉其实也不是很难,至少有K位不同,即至少有K位上是(1,0).
分析:
假设有K位不同,即有K个(1,0),有M-K个(1,1)和(0,0),用排列组合来算,
1.K位计算:C(k,m)种排列方式,每位上有两种可能,即2^k,因为比较的两个数实际上都在n中,所以再去掉重复情况,我们需要除以2, 则K位的种类为C(k,m)*2^(k-1);
2.m-k位的情况为C(m-k,m);
3.则K位相同的情况下有C(k,m)*2^(k-1)*C(m-k,m)种情况;
4.依次类推K+1,K+2·····,m;
5.求和得n。
没细想,稍微思考了下,可能不对,仅供参考
[解决办法]
int arr[m];
for (value in all)
{
for(i < m){
bit bits[m] = &value;
arr[i] += bits[i];
}
}
然后取出arr中的 最大的a个数,还有就是最小的b个数, a + b = k;
于是得出了这些数共同的k位。
然后。。。~
[解决办法]
这个编程序难度也许不大,不过证明似乎有些麻烦
建立一个临时数组,先加入0,然后从0开始顺序循环到2^m,如果这个数和每个临时数组里面的数都满足有k位不同则将该数加入临时数组,最后统计临时数组数目即可
[解决办法]
个人觉得,问题难度在于每次都判断是否满足至少K位不同的条件,不是在于如何去循环·
[解决办法]判断是否有K位不同是否可以用异或来判断?
[解决办法]这个就需要每一位都去判断了吧,会涉及移位,累加,异或,判断等操作,如果M值很大,计算量将非常大,个人觉得应该避免这个问题
[解决办法]不对,想错了。。。。
[解决办法]是错了,没考虑K+1位不同的数和K位不同的数之间可能不满足条件,那LZ看看这样行不行。后面m-k位也算的不对
先保证K位不同,即同前面:
1.K位计算:C(k,m)种排列方式,每位上有两种可能,即2^k,因为比较的两个数实际上都在n中,所以再去掉重复情况,我们需要除以2, 则K位的种类为C(k,m)*2^(k-1);
2.再去讨论M-K位
a.)其中没有不同时种类有2^(m-k)
b.)其中有1个不同时种类有2^(m-k-1)*C(1,k)
c.)其中有2个不同时种类有2^(m-k-2)*[C(1,k)c(1,2)+c(2,k)*c(2,2)]
........
其中有K个不同时种类有2^(m-k-k)*[C(1,k)c(1,k)+c(2,k)*c(2,k)...c(k,k)*c(k,k)]
........
其中有j个不同时(j>k)种类有2^(m-k-j)*[C(1,j)c(1,j)+c(2,j)*c(2,j)...c(k,j)*c(k,j)]
3.1和2中和相乘
[解决办法]是错了,没考虑K+1位不同的数和K位不同的数之间可能不满足条件,那LZ看看这样行不行。后面m-k位也算的不对
先保证K位不同,即同前面:
1.K位计算:C(k,m)种排列方式,每位上有两种可能,即2^k,因为比较的两个数实际上都在n中,所以再去掉重复情况,我们需要除以2, 则K位的种类为C(k,m)*2^(k-1);
2.再去讨论M-K位
a.)其中没有不同时种类有2^(m-k)
b.)其中有1个不同时种类有2^(m-k-1)-C(1,k)
c.)其中有2个不同时种类有2^(m-k-2)-[C(1,k)c(1,2)+c(2,k)*c(2,2)]
........
其中有K个不同时种类有2^(m-k-k)-[C(1,k)c(1,k)+c(2,k)*c(2,k)...c(k,k)*c(k,k)]
........
其中有j个不同时(j>k)种类有2^(m-k-j)-[C(1,j)c(1,j)+c(2,j)*c(2,j)...c(k,j)*c(k,j)]
3.1和2中和相乘
(应该是减,但还是错的,我哭····)
[解决办法]
这题本来就不简单啊。。
[解决办法]
很简单,可惜不好证明。不过还是能够证出来的。
#include <math.h>
long find_n( m, k )
{
return pow(2,(m-k+1));
}
[解决办法]集合划分问题。
每个数与其他数之间的“位不同”作为他们的区别度。
现在是在指定区别度的情况下,查找最大集合。
[解决办法]是的。