坚持每日Codeforces三题挑战:Day 3 - 题目详解(2025-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 = 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
		}
	}
}

题目三:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值