C. Sum of Substrings(贪心)

该博客主要讨论了一种针对含有111子串的字符串序列,通过交换字符来最大化得分的算法。当111不在序列首尾时,通过模拟移动111至首尾的过程,计算所需的最小交换次数。代码中定义了计算当前得分的函数,并根据不同的字符串开头和结尾情况,执行相应的字符交换策略,以求得最优解。

题目如下:

在这里插入图片描述

思路 or 题解

我们发现不在序列首尾的 111 对整体得分的贡献一定是 111111 (作为个位和十位各出现一次),而 111 开头的对得分的贡献为 101010 ,末尾111的对得分的贡献为 111 ,所以我们希望能有中间的111移到开头或者末尾去,如果中间没有111 也可以把开头的 111 移动到末尾去,模拟这个过程即可,一个位置的 111 移动到另一个位置需要消耗的交换次数是这两个位置之间的距离.

AC代码如下:

const int N = 100009;
int n, k;
char s[N];
int cal()
{
    int res = 0;
    for (int i = 2; i <= n; i++)
        res += (s[i - 1] - '0') * 10 + s[i] - '0';
    return res;
}
void solve()
{
    cin >> n >> k;
    cin >> s + 1;
    if (s[1] == '1' && s[n] == '1')
    {
        cout << cal() << '\n';
        return;
    }
    else if (s[1] == '1' && s[n] == '0')
    {

        for (int i = 2; i < n; i++)
        {
            if (s[i] == '1' && (n - i) <= k)
            {
                swap(s[i], s[n]);
                cout << cal() << '\n';
                return;
            }
        }
        if (n - 1 <= k)
        {
            swap(s[1], s[n]);
            cout << cal() << '\n';
            return;
        }
    }
    else if (s[1] == '0' && s[n] == '1')
    {
        for (int i = 2; i < n; i++)
        {
            if (s[i] == '1' && (i - 1) <= k)
            {
                swap(s[i], s[1]);
                cout << cal() << '\n';
                return;
            }
        }
    }
    else
    {
        int idx = n - 1;
        for (int i = n - 1; i > 1; i--)
        {
            if (s[i] == '1' && (n - i) <= k)
            {
                swap(s[i], s[n]);
                idx = i - 1;
                k -= (n - i);
                break;
            }
        }

        for (int i = 2; i <= idx; i++)
        {
            if (s[i] == '1' && (i - 1) <= k)
            {
                swap(s[i], s[1]);
                break;
            }
        }
    }
    cout << cal() << '\n';
}
int main()
{
    buff;
    int _;
    cin >> _;
    while (_--)
        solve();
}
时间限制:1000ms 内存限制:512MB 输入文件名:s.in 输出文件名:s.out 题目描述: 给定一个长度为 N 的只含小写字母的字符串 S,每次操作可以选择一个位置 1 ≤ x ≤ N 和一个小写字母 c,接着把 Sₓ 改为 c。 你需要操作若干次,使得操作结束后,每相邻 K 个字符都不同,求最少的操作次数。保证 1 ≤ K ≤ 13。 输入格式: 第一行一个整数 T,表示测试数据组数。 接下来 T 组测试数据,对于每组测试数据: 第一行两个整数 N, K,分别表示字符串长度和子串的长度。 第二行一个长度为 N 的字符串 S。 输出格式: 对于每组测试数据,输出一行一个整数表示最少的操作次数。 样例输入 1(input1): 5 6 3 abaaba 5 2 hooch 8 3 cherykid 9 3 abbabbaba 9 3 aabbaabba 样例输出 1(output1): 2 1 0 3 4 样例 #1 解释: 对于第一组数据,可以用 2 次操作把 S 改为 abcabc,每相邻三个字符组成的字符串分别是 abc、bca、cab、abc,都满足包含的字符互不相同。 对于第三组数据,请注意可以不进行操作。 数据范围: 对于所有数据,保证 1 ≤ T ≤ 10⁵,1 ≤ &sum;N ≤ 10⁶,1 ≤ K ≤ 13,S 中只含有小写字符。 子任务说明: 子任务 1:&sum;N ≤ 10,K ≤ 10,分值 10 子任务 2:&sum;N ≤ 100,K ≤ 10,分值 10 子任务 3:&sum;N ≤ 10³,K ≤ 13,分值 10 子任务 4:&sum;N ≤ 10⁵,K ≤ 3,分值 20 子任务 5:&sum;N ≤ 10⁵,K ≤ 13,分值 20 子任务 6:&sum;N ≤ 10⁶,K ≤ 13,分值 30 用C++ 14 With O2的语言写一段代码,不要超时,不要注释,用万能头,变量名用一个字母表示,最终代码写好后随便写5组边缘样例测试一下刚刚写的代码(把代码放进编译器输出检查),然后根据刚刚的代码测试修改代码,将这两段代码里的变量名用一个字母替代。代码加上空格,使代码有可读性(实在拿不到全分,也可以拿部分分,尽量多拿!)注意加上文件读写!!!!!!!!!!
07-12
04-03
<think>嗯,用户给了一段Java代码,看起来有问题。他们想了解这段代码或者得到解释。首先,我需要仔细看一下代码的结构。 代码是: for(String substring:substrings){ System.out.println(substrings); } 用户可能在这里犯了常见的错误。首先,这里使用的是增强型for循环,变量名是substring,但循环体内打印的是substrings,也就是集合本身,而不是每次迭代的substring。这会导致循环每次输出整个集合,而不是每个元素。这应该是个笔误,正确应该是System.out.println(substring);。 接下来,我需要确认substrings这个集合是否存在,是否已经正确初始化。如果substrings没有被定义或者为null,这段代码会抛出空指针异常。这也是需要注意的地方。 然后,我应该考虑可能的场景,用户可能在遍历一个字符串数组或列表,想逐个打印每个子字符串,但因为变量名打错,导致结果不符合预期。这时候需要指出变量名的正确使用,并给出修正后的代码示例。 另外,还要解释增强型for循环的工作原理,确保用户理解循环变量和集合的关系。可能还需要提到常见的错误类型,比如并发修改异常,如果在遍历过程中修改集合的话,但这里的问题更基础,是变量名错误。 总结用户的代码问题,主要是打印了集合对象而不是元素,需要修正变量名,并检查集合是否正确初始化。然后给出正确的代码示例,说明每个部分的作用,帮助用户理解哪里出错了,以及如何修复。</think>你提供的Java代码片段中存在一个常见的逻辑错误,具体分析如下: ### 原代码分析 ```java for(String substring:substrings){ System.out.println(substrings); } ``` #### 问题说明: 1. **变量误用**:循环变量声明为 `substring`(单数),但输出语句中错误地使用了集合变量 `substrings`(复数) 2. **预期行为偏离**:此代码会重复打印整个集合对象(如数组或列表)的地址/哈希值,而非逐个输出元素内容 ### 修正后的代码 ```java for(String substring:substrings){ System.out.println(substring); // 注意变量名改为单数 } ``` ### 关键知识点 1. **增强for循环结构**: ```java for(元素类型 变量名 : 集合/数组){ // 使用当前元素(变量名) } ``` 2. **正确执行条件**: - `substrings` 必须是已初始化的可迭代对象(如数组、List集合) - 如果 `substrings` 为null会抛出 `NullPointerException` ### 完整示例 ```java import java.util.Arrays; import java.util.List; public class Main { public static void main(String[] args) { List<String> substrings = Arrays.asList("A", "B", "C"); for(String substring : substrings){ System.out.println(substring); // 正确输出每个元素 } } } ``` ### 输出结果 ``` A B C ``` 建议检查代码中的变量命名一致性,这种错误通常是由于拼写疏忽造成的。在实际开发中,使用IDE的语法高亮功能可以快速识别此类问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Joanh_Lan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值