目录
除2!(贪⼼+堆)
题目解析
1.题目链接:登录---专业IT笔试面试备考平台_牛客网
2.题目描述
题目描述
给一个数组,一共有 n n\ n 个数。
你能进行最多 k k\ k 次操作。每次操作可以进行以下步骤:
- 选择数组中的一个偶数 aia_iai,将其变成 ai/2a_i/2ai/2 。
现在你进行不超过 k k\ k 次操作后,让数组中所有数之和尽可能小。请输出这个最小的和。
输入描述:
第一行输入两个正整数 n n\ n 和 k k\ k ,用空格隔开
第二行输入n n\ n 个正整数 aia_iai
数据范围:
1≤n≤100000,1≤k≤1091 ≤ n≤100000,1≤k≤10^91≤n≤100000,1≤k≤109
1≤ai≤1091≤a_i≤10^91≤ai≤109
输出描述:
一个正整数,代表和的最小值。
示例1
输入
5 3 2 4 8 10 11
5 3
2 4 8 10 11
输出
24
24
说明
对8操作2次,对10操作1次,最后的数组是2 4 2 5 11。可以证明这样的操作是最优的。
讲解算法原理
解法:
算法思路:
搞⼀个堆模拟⼀下就好了~
编写代码
c++算法代码:
cpp
#include <iostream>
#include <queue>
using namespace std;
typedef long long LL;
LL n, k;
priority_queue<LL> heap;
int main()
{
cin >> n >> k;
LL sum = 0, x;
while(n--)
{
cin >> x;
sum += x;
if(x % 2 == 0) heap.push(x);
}
while(heap.size() && k--)
{
LL t = heap.top() / 2;
heap.pop();
sum -= t;
if(t % 2 == 0) heap.push(t);
}
cout << sum << endl;
return 0;
}
java算法代码:
java
import java.util.*;
public class Main
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n = in.nextInt(), k = in.nextInt();
PriorityQueue<Integer> heap = new PriorityQueue<>((a, b) -> {
return b - a;
});
long sum = 0, x;
for(int i = 0; i < n; i++)
{
x = in.nextLong();
sum += x;
if(x % 2 == 0)
{
heap.add((int)x);
}
}
while(!heap.isEmpty() && k-- != 0)
{
long t = heap.poll() / 2;
sum -= t;
if(t % 2 == 0)
{
heap.add((int)t);
}
}
System.out.println(sum);
}
}
Fibonacci数列(Fib数列)
题目解析
1.题目链接:Fibonacci数列_牛客题霸_牛客网
2.题目描述
描述
Fibonacci数列是这样定义的:
F[0] = 0
F[1] = 1
for each i ≥ 2: F[i] = F[i-1] + F[i-2]
因此,Fibonacci数列就形如:0, 1, 1, 2, 3, 5, 8, 13, ...,在Fibonacci数列中的数我们称为Fibonacci数。给你一个N,你想让其变为一个Fibonacci数,每一步你可以把当前数字X变为X-1或者X+1,现在给你一个数N求最少需要多少步可以变为Fibonacci数。
输入描述:
输入为一个正整数N(1 ≤ N ≤ 1,000,000)
输出描述:
输出一个最小的步数变为Fibonacci数"
示例1
输入:
15
输出:
2
讲解算法原理
解法:
算法思路:
求斐波那契数列的过程中,判断⼀下:何时n会在两个fib数之间。
编写代码
c++算法代码:
cpp
#include <iostream>
using namespace std;
int n;
int main()
{
cin >> n;
int a = 0, b = 1, c = 1;
while(n > c)
{
a = b;
b = c;
c = a + b;
}
cout << min(c - n, n - b) << endl;
return 0;
}
java算法代码:
java
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息public class Main
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int a = 0, b = 1, c = 1;
while(n > c)
{
a = b;
b = c;
c = a + b;
}
System.out.println(Math.min(c - n, n - b));
}
}