#P1872. 第3题-最少的数组操作次数
-
1000ms
Tried: 62
Accepted: 20
Difficulty: 5
所属公司 :
京东
时间 :2024年8月10日
-
算法标签>贪心算法
第3题-最少的数组操作次数
题目思路
原题的答案有问题,有一种简单的方法是求出每个数最少需要多少次变换从0得到,求出最大的数量,然后每次都[1, n]所有元素进行操作,执行最大数量就可以得到结果,那些所需操作更少的数只需要在一开始为0的时候不停的乘以2即可,这样就还是0.
但是原题可能认为第一个操作不能是乘以2,所以只能通过相邻两个数的操作次数的差值来求解,假设第i个数的操作次数是x,第i+1个数的操作次数为y,如果y大于x,那么i+1和i这两个数可以共用x次操作,还需要y-x次的操作。如果y小于x,那么y就可以共享所有x的操作,这里记差值为0。所以直接将相邻数的操作次数的差值累加即可。
关于每个数的操作次数:只需要将每个数的二进制的1的数量和其最大位的位置相加即可,1的数量对应于+1,最大位置意味着*2(左移一位)。
代码
Java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int T = scanner.nextInt();
for (int t = 0; t < T; t++) {
int n = scanner.nextInt();
int[] b = new int[n];
for (int i = 0; i < n; i++) {
b[i] = scanner.nextInt();
}
int last = 0, ans = 0;
for (int v : b) {
int cnt = 0;
while (v > 0) {
if (v % 2 == 1) {
v -= 1;
} else {
v /= 2;
}
cnt++;
}
if (cnt > last) {
ans += cnt - last;
}
last = cnt;
}
System.out.println(ans);
}
}
}
C++
#include <iostream>
#include <vector>
using namespace std;
int main() {
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
vector<int> b(n);
for (int i = 0; i < n; i++) {
cin >> b[i];
}
int last = 0, ans = 0;
for (int v : b) {
int cnt = 0;
while (v > 0) {
if (v % 2 == 1) {
v -= 1;
} else {
v /= 2;
}
cnt++;
}
if (cnt > last) {
ans += cnt - last;
}
last = cnt;
}
cout << ans << endl;
}
return 0;
}
Python
T = int(input())
for _ in range(T):
n = int(input())
b = list(map(int, input().split()))
last, ans = 0, 0
for v in b:
cnt = 0
while v:
if v % 2 == 1:
v -= 1
else:
v //= 2
cnt += 1
if cnt > last:
ans += cnt - last
last = cnt
print(ans)
会员可通过查看《已通过》的提交记录来查看其他语言哦~
题目描述
小红有一个长度为n且值都为0的数组a。对于这个致组小红每次操作可以选择一个区间[l, r],对于[l,r]上的每一个数牛必须让其加一或者乘二(元素之间操作独立,可以选择些元素乘二,一些元素加一,但是区间内每个元素都要操作)
小红还有一个目标数组b,小红想知道对于初始数组a来说,其最少操作多少次可以将其变为b呢。
输入描述
第一行为,表示有t组数据
接下来有2t行,每组数据的第一行为一个n,第二行为n个整数,表示目标数组的元素b 1<=t<=10,1<=n<=105,1<=bi<=109,∑n<=105
输出描述
输出为t行,每行为一组答案表示小红的最小操作次数
样例
输入
2
5
1 1 2 1 1
5
1 2 3 4 5
输出
2
4
说明 说明 第一组数据中,小红第一次选择区间[1,5],让区间内所有元素加一,第二次小红选择区间[3,3],让元素乘二。
第二组数据中,小红第一次选择区间(1,5],让区间内所有元素加一。第二次小红选择区间[2,5],让区间元素加一。第三次小红选择区间[3,5],让a3加一,让a4,a5乘二。第四次小红选择区间[5,5],让元素加一