文章目录
2048最少的合成次数
■题目描述
有一个数字游戏叫做2048,此游戏的规则为,两个相同的数字能进行相加。例如:两个2可以相加,则相加后4的个数加一,2的个数会减二。
现在有一串数字,为目前已知的数字的数量。问至少还需要几次相加,才能获得2048 (题目保证能够相加得到2048)。
输入描述:
第一行为样例数T,代表后面会跟随工组测试数据。
每组测试数据输入10个数,分别代表
2,4,8,16,32,64,128,256,512,1024的个数。
每种数字的个数不超过1024。
输出描述:
对于每组数据, 输出一个数, 表示需要得到2048最少需要相加的次数。
输入
2
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 2
输出
10
1
个人思路: 作为程序员,对2,4,8,16,32,64,128,256,512,1024这一串数字真的很熟悉,所以自然想到了需要用位运算。这些数分别是2的1,2,3,4,5,6,7,8,9,10次方,而目标2048正好是2的11次方。
那就是说二进制位的第11位是0,需要有其它上述类型数字相加得到2048,使得结果的第11位为1。应该尽量选用高位去相加。
递归方法
void merge(vector<int> &array, int ×, int index) {
if (array[9] == 2)
return;
// 从大向小合并
if (array[index] > 1)
{
times += 1;
array[index] -= 2;
array[index + 1] += 1;
merge(array, times, index + 1);
return;
}
if (index > 0)
merge(array, times, index - 1);
}
int main() {
int n = 0;
vector<int> array(10);
cin >> n;
for (int i = 0; i < n; ++i) {
// 接收数据
for (int j = 0; j < 10; ++j)
cin >> array[j];
int times = 1;
merge(array, times, 8);
cout << times;
if (i + 1 != n)
cout << endl;
}
return 0;
}
循环方法
#include<iostream>
#include<vector>
#include<math.h>
using namespace std;
int main()
{
vector<int> data(10);
int ret = 0, n = -1, x;//n个数需要n-1次相加
cin >> x;
while (x--){
for (int i = 0; i < 10; i++)
cin >> data[i];
for (int i = 9; ret != 2048; i--)
{
if (ret == 2048)
break;
else if (i == -1)
{
ret += 2;
n++;
}
else
{
while (ret != 2048 && data[i] != 0){
ret += pow(2, i + 1);
n++, data[i]--;
}
}
}
printf("%d", n);
}
system("pause");
}