多多鸡让皮皮虾每次选择一个数字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);
}
}
}
} 通过所有用例。
import math
t = int(input())
for i in range(t):
n = int(input())
print(int(math.log(n, 2)) + 1)
二分,用1234 12345这种作为例子规律一下子就会出来
#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);
}
} #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;
} import math T = int(input()) for _ in range(T): N = int(input()) print(int(math.log2(N)) + 1)
#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;
} 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