多多鸡让皮皮虾每次选择一个数字X(1 <= X <= N),多多鸡就会把球数量大于等于X个的盒子里的球减少X个。
通过观察,皮皮虾已经掌握了其中的奥秘,并且发现只要通过一定的操作顺序,可以用最少的次数将所有盒子里的球变没。
那么请问聪明的你,是否已经知道了应该如何操作呢?
第一行,有1个整数T,表示测试用例的组数。
(1 <= T <= 100)
接下来T行,每行1个整数N,表示有N个魔术盒子。
(1 <= N <= 1,000,000,000)
共T行,每行1个整数,表示要将所有盒子的球变没,最少需要进行多少次操作。
3 1 2 5
1 2 3
这道题最容易想到的就是不停从中值减少,我也是这样的解法。
@牛客625413878号的代码非常简洁。数字转二进制,位数就是结果,太秀了,不发出来可惜了。
已经提醒本人写题解,等他写了我就删除这部分。
n = int(input()) for i in range(n): x = int(input()) print(len(bin(x))-2)
这是我的代码。
package main import "fmt" func main() { var t,n int fmt.Scan(&t) for i:=0;i<t;i++{ fmt.Scan(&n) ans:=1 for ;n>1;n/=2{ ans++ } fmt.Println(ans) } }
import java.util.Scanner; public class Main { public static void main(String[] args) { //根据规律可知,即算出该十进制的二进制表示的位数 //比如5,二进制表示为101,位数为3,则最少操作次数为3 Scanner sc = new Scanner(System.in); //接收测试用例个数 int count = sc.nextInt(); //创建数组接收 int[] nums = new int[count]; //创建结果数组 int[] ans = new int[count]; while (sc.hasNext()){ for (int i = 0; i <count ; i++) { nums[i] = sc.nextInt(); int temp = nums[i]; String s = Integer.toBinaryString(temp); ans[i] = s.length(); } for (int i:ans) { System.out.println(i); } } } }通过所有用例。
#include <iostream> /*本题可以先理解问题的核心,选择中间值进行减少是最佳: 当N为奇数时(N=2*a+1),减少中间的值(a+1)会使得两边都变成1到a的排序 例如N=7,先取4,则得到数组[1 2 3 0 1 2 3],此时问题变成当N为3; 当N为偶数时(N=2*a),没有中间数,但减少a或者a+1的值效果一样是最优情况 例如N=6,先取3,则得到数组[1 2 0 1 2 3],此时问题同样变成当N为3 所以求N的解就是求N/2再+1,则可以求利用递归原理求解本题,即f(N)=f(N/2)+1*/ //编写递归算法 int ballNum( long int n) { long int arr[] = { 0 }; if (n <= 0) { return -1; } if (n == 1 ) { return 1;//初始条件N=1 } if (n == 2) { return 2;//初始条件N=2 } else { return ballNum(n/2)+1; } } int main() { int T; std::cin >> T; //注意循环从1开始 for (int i = 1; i < T+1; i++) { long int num; std::cin >> num; std::cout << ballNum(num) << std::endl; } return 0; }
import math t = int(input()) for i in range(t): n = int(input()) print(int(math.log(n, 2)) + 1)二分,用1234 12345这种作为例子规律一下子就会出来
#include<stdio.h> #include<math.h> #define N 100 int main(){ int time; int a[N]; int d[N]; scanf("%d",&time); for(int i=0;i<time;i++){ scanf("%d", &a[i]); d[i]=(log(a[i])/log(2))+1; } for(int j=0;j<time-1;j++){ printf("%d\n",d[j]); } printf("%d",d[time-1]); return 0; }
#include <iostream> #include <math.h> using namespace std; int main(){ int t; cin>>t; for(int i=0;i<t;i++){ int a; cin>>a; cout<<(int(log(a)/log(2))+1)<<endl; //每次取中点,是正方形 }//for return 0; }
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int num = sc.nextInt(); for (int i = 0;i<num;i++){ int n = sc.nextInt(); System.out.println(cal(n)); } } public static int cal(int n){ if (n==1) return 1; if (n==2) return 2; else return 1+cal(n/2); } }
import math T = int(input()) for _ in range(T): N = int(input()) print(int(math.log2(N)) + 1)
const rl = require("readline").createInterface({ input: process.stdin }); var iter = rl[Symbol.asyncIterator](); const readline = async () => (await iter.next()).value; // 通过二分法来解决,每次取中间的数,后面的数字一次减x,再次寻找数组起始点与中间数的中间值,直到数组中间值等于a[0],就相当于求二分法的时间复杂度log(n)底数为2。然后通过分析,如果是2的整数倍,那么a[n]还需要一步操作,如果不是2的整数倍也需要对a[0]进行减1操作。所以就是求 log(n)+1 void async function () { // Write your code here var arr = [] while(line = await readline()){ arr.push(line) } // console.log("arr:",arr) for(var i=1;i<=arr[0];i++){ var result=parseInt(Math.log2(arr[i]))+1 console.log(result) } }()
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); // int[] nums = new int[] for (int i = 0; i < n; i++) { int cur = sc.nextInt(); System.out.println(getMinTimes2(cur)); } sc.close(); } private static int getMinTimes2(int n) { int t = 0; while (n > 0) { n /= 2; t++; } return t; } private static int getMinTimes(int n) { if (n == 1) { return 1; } int[] f = new int[n + 1]; f[1] = 1; f[2] = 2; for (int i = 3; i <= n; i++) { f[i] = Math.min(f[i / 2], f[(i + 1) / 2]) + 1; } return f[n]; } }
def magicBox(n): n = bin(n) l = len(n)-2 return l T = int(input()) for _ in range(T): N = int(input()) print(magicBox(N))
def qiu(N): if N==1: return 1 elif N==2: return 2 else: return qiu(N//2)+1 num=int(input()) nums=[] for i in range(num): a=int(input()) nums.append(a) for i in range(len(nums)): N=nums[i] print(qiu(N))使用递归,每次都选择的是N//2+1