链接:https://ac.nowcoder.com/acm/contest/940/A
来源:牛客网
kotori和糖果
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
kotori共有n块糖果,每块糖果的初始状态是分散的,她想把这些糖果聚在一堆。但她每次只能把两堆糖果合并成一堆。
已知把两堆数量为a和b的糖果聚在一堆的代价是|a-b|。
kotori想知道,她把这n块糖果聚在一堆的最小代价是多少?
输入描述:
第一行是一个正整数T,代表数据组数。
第二行到第T+1行,每行一个非负整数n,代表kotori的糖果总数量。
输出描述:
每行一个整数,代表kotori需要花费的最小代价。
示例1
输入
复制
2
5
6
输出
复制
2
2
说明
n=5时,kotori可以这样聚集糖果:
1 1 1 1 1
2 1 1 1
2 2 1
2 3
5
每一步的代价分别是0,0,1,1,总代价为2。
备注:
对于50%的数据,0<T≤100000, 0≤n≤100000
对于另外50%的数据,T=1 , 0≤n≤1e18
import java.util.Scanner;
public class Main{
public static long[] a = new long[1000005];
static long f(long x) {
if (x < 100005) return a[(int)x];
else{
long y = x / 2;
if (x % 2 == 1) return f(y) + f(y + 1) + 1;
else return 2 * f(y);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long N, n;
a[0] = 0;
a[1] = 0;
a[2] = 0;
a[3] = 1;
for (int i = 4; i < 100005; i++) {
if (i % 2 == 1) a[i] = a[i / 2] + a[i / 2 + 1] + 1;
else a[i] = 2 * a[i / 2];
}
N = sc.nextInt();
while (N > 0) {
N--;
long x = sc.nextLong();
System.out.println(f(x));
}
}
}
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;
/**
* Built using CHelper plug-in
* Actual solution is at the top
*/
public class Main {
public static void main(String[] args) {
InputStream inputStream = System.in;
OutputStream outputStream = System.out;
InputReader sc = new InputReader(inputStream);
PrintWriter out = new PrintWriter(outputStream);
Task solver = new Task();
solver.solve(1, sc, out);
out.close();
}
static class Task {
public static HashMap<Long,Long> map=new HashMap<Long,Long>();
public long dfs(long res) {
if((res&(res-1))==0)
return 0;
else
if(map.containsKey(res))
return map.get(res);
else
if((res&1)==1) {
long temp=dfs(res>>1)+dfs((res>>1)+1)+1;
map.put(res, temp);
return temp;
}
else {
long temp=dfs(res>>1)*2;
map.put(res, temp);
return temp;
}
}
public void solve(int testNumber, InputReader sc, PrintWriter out) {
int t=sc.nextInt();
for(int i=3;i<=1e5;i++)
dfs(i);
while(t-->0) {
long x=sc.nextLong();
out.println(dfs(x));
}
}
}
static class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
}
}