一个面试题:
在不超过最右边的数量的情况下任意组合,要求加起来不超过20280这个数字,但达成最接近的情况,现有一种方法为:1290*4+2990*5,差170,有没有更接近20280的答案:
数据如下:
4900*1
3790*2
2990*5//意思是不能超过5次,但可以使用1次,2次,3次,4次,5次。
2390*3
1990*5
1290*4
程序如下:
void main()
{
int a[] = {4900,
3790 * 1,3790*2,
2990 * 1,2990 * 2,2990 * 3,2990 * 4,2990*5,
2390 * 1,2390 * 2,2390*3,
1990 * 1,1990 * 2,1990 * 3,1990 * 4,1990*5,
1290 * 1,1290 *2,1290 * 3,1290*4 };
int len = 20;
int i;
//int cnt[1048575] = {0};
int tempMin = 0xfff;
int cond;
for ( i= 0; i < (1 << len); i++) //循环需要0 到2^len-1 次。
{
int sum = 0;
for (int j = 0; j < len; j++)
{
if ((i&(1 << j)) != 0) //这个地方很巧妙。
{
sum = sum + a[j];
}
//cout <<i<<" "<<j<<" "<< sum << " " << 20280 - sum << endl;
}
if ((abs(20280 - sum) < tempMin)&&((i&(0x6))<=4)&&((i&(0xf8))<=0x80)&&((i&(0x700))<=0x400)&&((i&(0xf800))<=8000)&&((i&(0xf0000))<=80000))
{
tempMin = abs(20280 - sum);
cond = i;
if (tempMin == 0)
cout << i << " " << tempMin << endl;
}
}
cout <<tempMin<<" "<< cond << endl;
}
最终答案是:
2390*2 2990*1 3790*2 4900
这个程序的主要思想是使用了一个位映射的思想解决了这个需要好多次循环才能解决的问题。
同时我们可以看到对于10M左右的int型数组,VS的栈好像不能成功分配,但是不考虑分配的话,直接使用,运算速度是相当快的,运算一遍一秒不到。