每天坚持写三道题第三天 (今天写点简单的,剩下去刷力扣了)
今日题目:
题目一:
题目大意:
给你一个数组,每次操作中,当数组中还有数字的时候,你可以进行以下的操作:
第一次操作可以选择任意的数字,拿掉他
第二次操作开始,你每次可以选择拿一个数字,但是这个数字的奇偶性必须跟上一个拿的数字不同
如果无法拿数字,结束操作
现在你进行若干次操作,你需要让数组剩下的数字的和最小
解题思路:
根据题目意思,我们可以注意到:
设奇数的数量为cnt1, 偶数的数量为cnt2,
当cnt1 != cnt2的时候
我们肯定可以拿完较小的那一堆
假设cnt1 < cnt2
那么我们可以拿完奇数,并且拿cnt2个偶数
如果我们刚开始就拿偶数的话,
最后我们还能再拿一个偶数
实现的话,可以把奇数偶数分开,然后排序
代码(C++):
void solve() {
int n;
std::cin >> n;
std::vector<int> nums1, nums2;
i64 sum = 0;
for (int i = 0; i < n; i++) {
int x;
std::cin >> x;
sum += x;
if (x % 2) {
nums1.push_back(x);
} else {
nums2.push_back(x);
}
}
std::sort(nums1.begin(), nums1.end(), std::greater<>());
std::sort(nums2.begin(), nums2.end(), std::greater<>());
int n1 = nums1.size(), n2 = nums2.size();
i64 ans = 0;
for (int i = 0; i < std::min(n1, n2); i++) {
ans += (nums1[i] + nums2[i]);
}
if (n1 > n2) {
ans += nums1[n2];
} else if (n2 > n1) {
ans += nums2[n1];
}
std::cout << sum - ans;
}
题目二:
题目大意:
定义幸运数字为,只包含4和7的数字,并且4和7的数量相等
比如47, 74, 4477这些
现在给你一个数字n,你需要找出大于等于n的所有数字中,最小的幸运数字
解题思路:
我们设题目要求的最小的幸运数字为ans
我们可以注意到
当数字n的长度len为奇数的时候,ans的长度肯定为len + 1
当n的长度len为偶数的时候,ans的长度为len或者len + 2
n最多为1e9
那么答案的最多为1e11
可以计算出,在这个长度内,幸运数字的个数为350个
那么我们可以用搜索的方式,快速计算出每一个幸运数字,然后排序,查找即可
代码(C++):
int main() {
int n;
std::cin >> n;
std::vector<i64> nums;
std::function<void(i64, int, int)> dfs;
dfs = [&](i64 num, int cnt4, int cnt7) {
if (num >= 1e11) {
return;
}
if (cnt4 == cnt7) {
nums.push_back(num);
}
dfs((num * 10) + 4, cnt4 + 1, cnt7);
dfs((num * 10) + 7, cnt4, cnt7 + 1);
};
dfs(0, 0, 0);
std::sort(nums.begin(), nums.end());
for (i64 num : nums) {
if (num >= n) {
std::cout << num << " ";
break;
}
}
}
题目三:
题目大意:
现在有一个数X,你需要找到两个数字a, b满足LCM(a, b) = X,并且max(a, b)最小
解题思路:
a和b的最小公倍数是x,那么也就是说a * b = x
我们可以枚举从1 到 sqrt(x)
查看是否是x的因数,对比max(a, b)即可
代码(C++):
#include <bits/stdc++.h>
using i64 = long long;
i64 lcm(i64 a, i64 b) {
return 1LL * a * b / std::gcd(a, b);
}
int main() {
i64 n;
std::cin >> n;
i64 mx = LLONG_MAX;
i64 resa = 0, resb = 0;
for (i64 a = 1; 1LL * a * a <= n; a++) {
if (n % a == 0) {
i64 b = n / a;
if (lcm(a, b) == n) {
i64 cur_max = std::max(a, b);
if (cur_max < mx) {
mx = cur_max;
resa = a;
resb = b;
}
}
}
}
std::cout << resa << " " << resb;
}
Python语言写法:
题目一:
def solve():
n = int(input())
a = list(map(int, input().split()))
nums1 = sorted([x for x in a if x % 2], reverse=True)
nums2 = sorted([x for x in a if x % 2 == 0], reverse=True)
n1, n2 = len(nums1), len(nums2)
ans = 0
for i in range(min(n1, n2)):
ans += nums1[i] + nums2[i]
if n1 > n2:
ans += nums1[n2]
elif n1 < n2:
ans += nums2[n1]
print(sum(a) - ans)
题目二:
def solve():
n = int(input())
nums = []
def dfs(num: int, cnt4: int, cnt7: int) -> None:
if num >= 1e11:
return
if cnt4 == cnt7:
nums.append(num)
dfs(num * 10 + 4, cnt4 + 1, cnt7)
dfs(num * 10 + 7, cnt4, cnt7 + 1)
dfs(0, 0, 0)
nums.sort()
for num in nums:
if num >= n:
print(num)
break
题目三:
Go语言写法:
题目一:
package main
import (
"bufio"
. "fmt"
"os"
"sort"
)
var (
in = bufio.NewReader(os.Stdin)
out = bufio.NewWriter(os.Stdout)
)
func main() {
defer out.Flush()
solve()
}
func solve() {
n := 0
Fscan(in, &n)
nums1 := []int{}
nums2 := []int{}
sum := 0
for i := 0; i < n; i++ {
x := 0
Fscan(in, &x)
sum += x
if x%2 == 1 {
nums1 = append(nums1, x)
} else {
nums2 = append(nums2, x)
}
}
sort.Ints(nums1)
sort.Ints(nums2)
ans := 0
n1, n2 := len(nums1), len(nums2)
for i := 0; i < min(n1, n2); i++ {
ans += nums1[i] + nums2[i]
}
if n1 > n2 {
ans += nums1[n2]
} else if n1 < n2 {
ans += nums2[n1]
}
Fprintln(out, sum-ans)
}
题目二:
package main
import (
"bufio"
. "fmt"
"os"
"sort"
)
var (
in = bufio.NewReader(os.Stdin)
out = bufio.NewWriter(os.Stdout)
)
func main() {
defer out.Flush()
solve()
}
func solve() {
n := 0
Fscan(in, &n)
nums := []int{}
var dfs func(num, cnt4, cnt7 int)
dfs = func(num, cnt4, cnt7 int) {
if num >= 1e11 {
return
}
if cnt4 == cnt7 {
nums = append(nums, num)
}
dfs(num*10+4, cnt4+1, cnt7)
dfs(num*10+7, cnt4, cnt7+1)
}
dfs(0, 0, 0)
sort.Ints(nums)
for _, num := range nums {
if num >= n {
Fprintln(out, num)
break
}
}
}