09.24毒(已改编)-三语言题解

💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历

👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸

✨ 笔试合集传送们 -> 🧷学长刷题笔记

🍒 本专栏已收集 140+ 套题 🍄 题面描述等均已改编,如果和你实际看到的题面描述不一样请理解,做法和题目本质基本不变。

🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力 💞

alt

🌈 毒秋招笔试,来啦!!!

🍥 本次很多粉丝反馈只做出来第一题,是的这次后面两题都不好做,T2的贪心容易想歪,T3也需要一些思维+图论的知识,总体难度不低

1️⃣ 这题比较打卡,但要对于剩余次数的处理

2️⃣ 贪心,考虑每个点最多被换两次,所以直接对其下标的位置进行贪心

3️⃣ 图论+最短路+思维题,先dijkstra跑一遍最短路后,然后判断新的边是否必须加即可

🫚 01.字符串大小写转换 评测链接🔗

问题描述

K小姐拿到了一个由大小写字母构成的字符串,长度为 。她想通过 次操作,将字符串中尽可能多的字母转换为大写字母。每次操作,她可以选择字符串中的任意一个字母,将其从小写转换为大写,或从大写转换为小写。

请你帮助K小姐计算,经过 次操作后,字符串中最多能有多少个大写字母?

输入格式

第一行包含两个正整数 ,分别表示字符串的长度和操作次数,两个数之间用空格隔开。

第二行包含一个长度为 的字符串,仅由大小写字母构成。

输出格式

输出一个整数,表示经过 次操作后,字符串中最多能有的大写字母数量。

样例输入

1 3
A

样例输出

0

样例解释

对于样例,字符串只有一个字母。无论操作多少次,最终的字符串要么是 "A",要么是 "a"。因此,最多只能有 0 个大写字母。

数据范围

题解

这道题可以这样考虑:先统计字符串中原本有多少个小写字母和大写字母。

  • 如果操作次数 足够多,那么可以先把所有小写字母都转换成大写字母。
  • 如果 还有剩余,再考虑是否需要把一些大写字母转换回小写字母。

统计字符串中小写字母的数量 和大写字母的数量

  1. 如果 ,说明操作次数足够将所有小写字母转换为大写字母。此时我们先把所有小写字母转换为大写字母,剩余的操作次数为
    • 如果 是偶数,那么我们不需要再进行转换,因为偶数次的转换会让字母的大小写状态回到原点。此时大写字母的数量就是字符串的总长度
    • 如果 是奇数,那么我们需要再将一个大写字母转换为小写字母。此时大写字母的数量就是
  2. 如果 ,说明操作次数不足以将所有小写字母转换为大写字母。此时我们只需要将 个小写字母转换为大写字母即可。最终的大写字母数量为

参考代码

  • Python
def solve(n, k, s):
    # 统计小写字母和大写字母的数量
    lower = sum(c.islower() for c in s)
    upper = n - lower
    
    if k >= lower:
        # 操作次数足够将所有小写字母转换为大写字母
        extra = k - lower
        if extra % 2 == 0:
            return n
        else:
            return n - 1
    else:
        # 操作次数不足以将所有小写字母转换为大写字母
        return upper + k

# 读取输入
n, k = map(int, input().split())
s = input().strip()

# 调用函数并输出结果
print(solve(n, k, s))
  • Java
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int k = sc.nextInt();
        String s = sc.next();
        
        System.out.println(solve(n, k, s));
    }
    
    public static int solve(int n, int k, String s) {
        // 统计小写字母和大写字母的数量
        int lower = 0;
        for (char c : s.toCharArray()) {
            if (Character.isLowerCase(c)) {
                lower++;
            }
        }
        int upper = n - lower;
        
        if (k >= lower) {
            // 操作次数足够将所有小写字母转换为大写字母
            int extra = k - lower;
            if (extra % 2 == 0) {
                return n;
            } else {
                return n - 1;
            }
        } else {
            // 操作次数不足以将所有小写字母转换为大写字母
            return upper + k;
        }
    }
}
  • Cpp
#include <iostream>
#include <string>
using namespace std;

int solve(int n, int k, string s) {
    // 统计小写字母和大写字母的数量
    int lower = 0;
    for (char c : s) {
        if (islower(c)) {
            lower++;
        }
    }
    int upper = n - lower;
    
    if (k >= lower) {
        // 操作次数足够将所有小写字母转换为大写字母
        int extra = k - lower;
        if (extra % 2 == 0) {
            return n;
        } else {
            return n - 1;
        }
    } else {
        // 操作次数不足以将所有小写字母转换为大写字母
        return upper + k;
    }
}

int main() {
    int n, k;
    string s;
    cin >> n >> k >> s;
    
    cout << solve(n, k, s) << endl;
    
    return 0;
}

🎀 02.K小姐的珠宝交换评测链接🔗

问题描述

K小姐是一位珠宝设计师,她有一串由 颗宝石组成的项链。这些宝石分别由 标号,且没有重复的宝石。

为了让项链看起来更加美观,K小姐可以选择相邻的两颗宝石进行交换。不过,每颗宝石最多只能被交换两次。

经过若干次交换后,K小姐希望得到一串字典序最大的项链。所谓字典序,就是从项链的第一颗宝石开始,逐个比较对应位置宝石的标号大小,直到找到第一个不同的宝石,通过比较这两颗宝石的标号大小来决定两串项链的字典序大小。

现在,K小姐想知道,在满足每颗宝石最多被交换两次的前提下,她能得到的字典序最大的项链是什么样的?

输入格式

第一行包含一个正整数 ,表示项链的宝石数量。

第二行包含 个由空格分隔的正整数 ,表示初始时项链上每颗宝石的标号。

输出格式

输出一行,包含 个由空格分隔的正整数,表示字典序最大的项链中每颗宝石的标号。

样例输入

8
3 7 2 1 6 5 4 8

样例输出

7 3 6 5 2 1 8 4

数据范围

题解

贪心

假设当前正在考虑第 个位置的宝石。如果这颗宝石已经被交换过两次了,那我们就不能再移动它,只能考虑下一个位置。

如果这颗宝石还可以交换,我们就在它之后的宝石中(最多往后看两个位置),找到标号最大的那颗宝石,将它交换到第 个位置。

为什么最多只看后面两个位置呢?

  • 因为每颗宝石最多只能交换两次,如果它后面的宝石要移动到第 个位置,就要交换至少 次。所以我们最多只能考虑 这两个位置。

参考代码

  • Python
def rearrange_jewelry(N, jewelry):
    # 记录每颗宝石的交换次数
    swap_count = [2] * (N + 1)  
    
    for i in range(N):
        if swap_count[jewelry[i]] == 0:
            continue
        
        max_idx = i
        for j in range(i + 1, min(N, i + 3)):
            if swap_count[jewelry[j]] < (j - i):
                break
            if jewelry[j] > jewelry[max_idx]:
                max_idx = j
        
        if max_idx != i:
            max_val = jewelry[max_idx]
            for j in range(max_idx, i, -1):
                jewelry[j] = jewelry[j - 1]
                swap_count[jewelry[j]] -= 1
            jewelry[i] = max_val
            swap_count[jewelry[i]] -= (max_idx - i)
    
    return jewelry

# 读取输入
N = int(input())
jewelry = list(map(int, input().split()))

# 调用函数
result = rearrange_jewelry(N, jewelry)

# 输出结果
print(' '.join(map(str, result)))

  • Java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        
        // 读取宝石数量
        int N = Integer.parseInt(br.readLine());
        
        // 读取初始项链
        int[] jewelry = Arrays.stream(br.readLine().split(" "))
                             .mapToInt(Integer::parseInt)
                             .toArray();
        
        // 调用函数
        int[] result = rearrangeJewelry(N, jewelry);
        
        // 输出结果
        System.out.println(Arrays.toString(result).replaceAll("[\\[\\],]", ""));
    }
    
    private static int[] rearrangeJewelry(int N, int[] jewelry) {
        // 记录每颗宝石的交换次数
        int[] swapCount = new int[N + 1];
        Arrays.fill(swapCount, 2);
        
        for (int i = 0; i < N; i++) {
            if (swapCount[jewelry[i]] == 0) {
                continue;
            }
            
            int maxIdx = i;
            for (int j = i + 1; j < Math.min(N, i + 3); j++) {
                if (swapCount[jewelry[j]] < (j - i)) {
                    break;
                }
                if (jewelry[j] > jewelry[maxIdx]) {
                    maxIdx = j;
                }
            }
            
            if (maxIdx != i) {
                int maxVal = jewelry[maxIdx];
                System.arraycopy(jewelry, i, jewelry, i + 1, maxIdx - i);
                System.arraycopy(swapCount, jewelry[i], swapCount, jewelry[i + 1], maxIdx - i);
                jewelry[i] = maxVal;
                swapCount[jewelry[i]] -= (maxIdx - i);
                
                for (int j = i + 1; j <= maxIdx; j++) {
                    swapCount[jewelry[j]]--;
                }
            }
        }
        
        return jewelry;
    }
}
  • Cpp
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

vector<int> rearrange_jewelry(int N, vector<int>& jewelry) {
    // 记录每颗宝石的交换次数
    vector<int> swap_count(N + 1, 2);
    
    for (int i = 0; i < N; i++) {
        if (swap

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

学长刷题笔记 文章被收录于专栏

这里收集了超全的刷题笔记,欢迎大家的订阅,会持续跟新的

全部评论

相关推荐

2 3 评论
分享
牛客网
牛客企业服务