Aaronson 一道思维题

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 (0im0≤i≤m) is non-negative.

InputThere are multiple test cases. The first line of input contains an integer T(1T105)(1≤T≤105), indicating the number of test cases. For each test case:

The first contains two integers nn and m(0n,m109)(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\n", ans);
16     }
17     return 0;



猜你喜欢

转载自www.cnblogs.com/ghosh/p/12630219.html