坚持每日Codeforces三题挑战:Day 1 - 题目详解(2025-04-14,难度:1300, 1400, 1700)

每天坚持写三道题目第一天

今日题目:

Problem - F - Codeforces 1300

Problem - C - Codeforces 1400

Problem - F1 - Codeforces 1700

目录

题目一:

题目大意:

解题思路:

代码(C++):

题目二:

题目大意:

解题思路:

代码(C++):

 题目三:

题目大意:

解题思路:

代码(C++):

Python写法:

题目一:

题目二:

题目三:

Go写法:

题目一:

题目二:

题目三:


题目一:

Problem - F - Codeforces

题目大意:

给你一个长度为n的数组a,你需要确定是否存在三个不同的索引 i、j、k,使得 ai​+aj​+ak​ 的个位数是3

解题思路:

只需要关注个位数字,并且只需要判断是否存在三个相加的个位数

那么,我们首先可以统计这个数组中每个个位数出现的次数,并且只需要最多取三次放在一个新的数组中去

对于新的数组,这个数组大小最多为30,我们套三个循环找三个数字相加的个位数即可

具体可以看实现代码

代码(C++):

void solve() {
    int n;
    std::cin >> n;

    int cnt[10]{};

    std::vector<int> a;
    for (int i = 0; i < n; i++) {
        int num;
        std::cin >> num;

        num %= 10;
        if (cnt[num] < 3) {
            cnt[num]++;
            a.push_back(num);
        }
    }

    n = a.size();
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            for (int k = j + 1; k < n; k++) {
                if ((a[i] + a[k] + a[j]) % 10 == 3) {
                    std::cout << "YES\n";
                    return;
                }
            }
        }
    }

    std::cout << "NO\n";
}

题目二:

Problem - C - Codeforces

题目大意:

题目定义了:

团队的实力: 一个团队的实力为这个团队实力最小的乘上这个团队的人数

现在有n个人,每个人的实力为ai,并且给你一个数字x

现在把这个这n个人分成若干个团队,你需要求出

最多能分出多少个实力大于等于x的团队

解题思路:

如果你是一个实力大于x的人,你一个人就可以组队了

如果你是一个实力小于x的人,你如何才能组一个队并且使用尽可能少的人?

很明显,你可以找一些实力大于你的人,然后,你就作为那个最小值,直到人数乘以你的实力刚好够的时候,就可以用尽可能少的人

现在要组建尽可能多的团队,所以你不能浪费别人的实力,你每次找人组队的时候,都需要找尽可能实力跟你接近的,并且都大于你的实力

具体实现就是:

对实力进行排序,从实力最高的开始进行遍历,

也就是每次遍历到ai,ai就是为当前队伍的最小值

并且记录队伍的长度,当队伍实力大于x的时候

也就是前面的可以组一队了,让当前长度等于0即可

此方法是最不浪费每个人实力的方法

代码(C++):

void solve() {
    int n, x;
    std::cin >> n >> x;

    std::vector<int> a(n);
    for (int i = 0; i < n; i++) {
        std::cin >> a[i];
    }

    std::sort(a.begin(), a.end(), std::greater<>());

    int ans = 0, cur = 0;
    for (int i = 0; i < n; i++) {
        cur++;
        if (1LL * cur * a[i] >= x) {
            ans++;
            cur = 0;
        }
    }

    std::cout << ans << "\n";
}

 题目三:

Problem - F1 - Codeforces
 

题目大意:

题目定义了:

平衡字符串: 在字符串中,'+'字符的数量和'-'字符数量相同

操作: 可以选择一个相邻的两个'-'字符,把其变成一个'+'字符

有前途的字符串: 可以通过任意操作次数(可以为零次)把一个字符串变成平衡字符串

子字符串: 一个字符串一段连续的字串,自身也是本身的子字符串

现在给你一个字符串,你需要判断它包含的有前途子字符串个数

解题思路:

我们首先可以注意到: 在一个字符串中,如果'-'字符比'+'字符多,那么必有至少一对'-'是相邻的

也就是说,只要'-'字符比'+'字符多,那么可以进行操作

那么如何才能使得字符串变成平衡字符串呢?

我们可以设cnt1 = '-'的数量, cnt2 = '+'的数量, x = cnt1 - cnt2

对于平衡字符串,x 为 0

每次操作中,'-'字符都会减少两个,'+'字符会增加一个

也就是说 x会减少3

那么也就可以得出结论:

要使得一个字符串是有前途的字符串,那么这个字符串的x必须大于0,并且为3的倍数

要快速求一段字符串的x,我们可以用"前缀和"思想,具体看代码实现

代码(C++):

#include <bits/stdc++.h>

void solve() {
    int n;
    std::cin >> n;

    std::string s;
    std::cin >> s;

    std::vector<int> pref1(n + 1);
    for (int i = 0; i < n; i++) {
        if (s[i] == '+') {
            pref1[i + 1] = pref1[i] - 1;
        } else {
            pref1[i + 1] = pref1[i] + 1;
        }
    }

    int ans = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < i; j++) {
            if (pref1[i + 1] >= pref1[j] && (pref1[i + 1] - pref1[j]) % 3 == 0) {
                ans++;
            }
        }
    }

    std::cout << ans << "\n";
}

int main() {
    int t;
    std::cin >> t;
    
    while (t--) {
        solve();
    }
}

Python写法:

题目一:

def solve():
    n = int(input())
 
    nums = list(map(int, input().split()))
 
    a = []
    cnt = [0] * 10
    for num in nums:
        num %= 10
        if cnt[num] < 3:
            cnt[num] += 1
            a.append(num)
    
    n = len(a)
    for i in range(n):
        for j in range(i+ 1, n):
            for k in range(j + 1, n):
                if (a[i] + a[j] + a[k]) % 10 == 3:
                    print("YES")
                    return
    
    print("NO")

题目二:

def solve():
    n, x = map(int, input().split())
    a = list(map(int, input().split()))

    a.sort(reverse=True)

    ans = 0
    cur = 0
    for val in a:
        cur += 1
        if val * cur >= x:
            ans += 1
            cur = 0

    print(ans)

题目三:

def solve():
    n = int(input())
    s = input()

    pref = [0] * (n + 1)
    for i in range(n):
        if s[i] == '+':
            pref[i + 1] = pref[i] - 1
        else:
            pref[i + 1] = pref[i] + 1
    
    ans = 0
    for i in range(n):
        for j in range(i):
            if pref[i + 1] >= pref[j] and (pref[i + 1] - pref[j]) % 3 == 0:
                ans += 1
    
    print(ans)

Go写法:

题目一:

package main

import (
	"bufio"
	. "fmt"
	"os"
)

var (
	in  = bufio.NewReader(os.Stdin)
	out = bufio.NewWriter(os.Stdout)
)

func main() {
	defer out.Flush()

	var T int
	for Fscan(in, &T); T > 0; T-- {
		solve()
	}
}

func solve() {
	n := 0
	Fscan(in, &n)

	a := []int{}
	cnt := [10]int{}

	for range n {
		num := 0
		Fscan(in, &num)

		num %= 10
		if cnt[num] < 3 {
			cnt[num]++
			a = append(a, num)
		}
	}

	n = len(a)
	for i := 0; i < n; i++ {
		for j := i + 1; j < n; j++ {
			for k := j + 1; k < n; k++ {
				if (a[i]+a[j]+a[k])%10 == 3 {
					Fprintln(out, "YES")
					return
				}
			}
		}
	}

	Fprintln(out, "NO")
}

题目二:

package main

import (
	"bufio"
	. "fmt"
	"os"
	"sort"
)

var (
	in  = bufio.NewReader(os.Stdin)
	out = bufio.NewWriter(os.Stdout)
)

func main() {
	defer out.Flush()

	var T int
	for Fscan(in, &T); T > 0; T-- {
		solve()
	}
}

func solve() {
	var n, x int
	Fscan(in, &n, &x)

	a := make([]int, n)
	for i := range a {
		Fscan(in, &a[i])
	}

	sort.Slice(a, func(i, j int) bool {
		return a[i] > a[j]
	})

	ans := 0
	cur := 0
	for i := range a {
		cur++
		if cur*a[i] >= x {
			ans++
			cur = 0
		}
	}

	Fprintln(out, ans)
}

题目三:

package main

import (
	"bufio"
	. "fmt"
	"os"
)

var (
	in  = bufio.NewReader(os.Stdin)
	out = bufio.NewWriter(os.Stdout)
)

func main() {
	defer out.Flush()

	var T int
	for Fscan(in, &T); T > 0; T-- {
		solve()
	}
}

func solve() {
	n := 0
	Fscan(in, &n)

	s := ""
	Fscan(in, &s)

	pref := make([]int, n+1)
	for i := 0; i < n; i++ {
		if s[i] == '+' {
			pref[i+1] = pref[i] - 1
		} else {
			pref[i+1] = pref[i] + 1
		}
	}

	ans := 0

	for i := 0; i < n; i++ {
		for j := 0; j < i; j++ {
			if pref[i+1] >= pref[j] && (pref[i+1]-pref[j])%3 == 0 {
				ans++
			}
		}
	}

	Fprintln(out, ans)
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值