Recently, Peter saw the equation x0+2x1+4x2+...+2mxm=nx0+2x1+4x2+...+2mxm=n. He wants to find a solution (x0,x1,x2,...,xm)(x0,x1,x2,...,xm) in such a manner that ∑i=0mxi∑i=0mxi is minimum and every xixi (0≤i≤m0≤i≤m) is non-negative.
InputThere are multiple test cases. The first line of input contains an integer TT (1≤T≤105)(1≤T≤105), indicating the number of test cases. For each test case:
The first contains two integers nn and mm (0≤n,m≤109)(0≤n,m≤109).OutputFor each test case, output the minimum value of ∑i=0mxi∑i=0mxi.
Sample Input
10 1 2 3 2 5 2 10 2 10 3 10 4 13 5 20 4 11 11 12 3
Sample Output
1 2 2 3 2 2 3 2 3 2
题意:进行T次询问,每次给你n和m,表示x0+2x1+4x2+...+2mxm=n的方程中,x0+x1+x2+……+xm的最小值
分析:我们来看x前面的系数,分别是1,2,4,……,2的m次方,这是不是和二进制有点像?
二进制表示一个数,就是从右至左依次为2的0次方,2的1次方,2的2次方……
由于题目让我们求x0+x1+x2+...+xm的最小值,我们可以从二进制的高位向低位来选数,一个数除以一个越大的数,商(也就是x)越小。这样这道题就解决了。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 int T, n, m; 4 int main(){ 5 scanf("%d", &T); 6 while (T--){ 7 int ans = 0 ; 8 scanf("%d%d", &n, &m); 9 if (m >=32) m = 32;//n在int范围内 10 for (int i = m; i >= 0; i--){ 11 int x = pow(2, i); 12 ans += n / x;//每次选n/x份 13 n %= x; 14 } 15 printf("%d ", ans); 16 } 17 return 0;