坚持每日Codeforces三题挑战:Day 3 - 题目详解(2024-04-16,难度:900, 1200, 1200)
每天坚持写三道题第三天 (今天写点简单的,剩下去刷力扣了)
今日题目:
Problem - B - Codeforces 900
Problem - B - Codeforces 1300
Problem - D - Codeforces 1400
题目一:
Problem - B - Codeforces
题目大意:
给你一个数组,每次操作中,当数组中还有数字的时候,你可以进行以下的操作:
第一次操作可以选择任意的数字,拿掉他
第二次操作开始,你每次可以选择拿一个数字,但是这个数字的奇偶性必须跟上一个拿的数字不同
如果无法拿数字,结束操作
现在你进行若干次操作,你需要让数组剩下的数字的和最小
解题思路:
根据题目意思,我们可以注意到:
设奇数的数量为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;}}
}
题目三:
Problem - C - Codeforces
题目大意:
现在有一个数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 = 0for 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:returnif 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 mainimport ("bufio". "fmt""os""sort"
)var (in = bufio.NewReader(os.Stdin)out = bufio.NewWriter(os.Stdout)
)func main() {defer out.Flush()solve()
}func solve() {n := 0Fscan(in, &n)nums1 := []int{}nums2 := []int{}sum := 0for i := 0; i < n; i++ {x := 0Fscan(in, &x)sum += xif x%2 == 1 {nums1 = append(nums1, x)} else {nums2 = append(nums2, x)}}sort.Ints(nums1)sort.Ints(nums2)ans := 0n1, 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 mainimport ("bufio". "fmt""os""sort"
)var (in = bufio.NewReader(os.Stdin)out = bufio.NewWriter(os.Stdout)
)func main() {defer out.Flush()solve()
}func solve() {n := 0Fscan(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}}
}