C. Letters【1000 / 双指针】

本文介绍如何使用C++实现解决CodeForces 978/C题目中的区间覆盖问题,通过优化数组操作找到最小操作次数。核心算法涉及动态规划和数组操作技巧。

在这里插入图片描述
https://codeforces.com/problemset/problem/978/C

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5*2+10;
int n,m;
LL a[N],b[N];
int main(void) 
{
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=m;i++) cin>>b[i];
	LL sum=0,i=1,j=1; 
	while(i<=m)
	{
		while(sum+a[j]<b[i]) sum+=a[j],j++;
		cout<<j<<" "<<b[i]-sum<<endl;
		i++;
	}
}
<think>题目要求:将legacy_map结构(按分数分组存储大写字母)转换为new_map结构(每个字母小写单独存储分数) 函数原型:int convert(const legacy_map *input, const size_t input_len, new_map **output); 步骤: 1. 遍历legacy_map数组,计算总共需要多少个new_map结构(即统计每个legacy_map中keys字符串的长度之和)。 2. 根据计算的总数,动态分配一个new_map数组,并将指针赋值给*output。 3. 再次遍历legacy_map数组,对于每个legacy_map元素,遍历其keys字符串中的每个字符: 将大写字母转换为小写字母(使用tolower函数), 在new_map数组中为每个字母创建一个元素,key为小写字母,value为当前legacy_map的value。 4. 返回动态分配的new_map数组的长度(即总字母个数)。 注意:题目要求输出是小写字母。 考虑:输入可能包含空指针或空字符串?但根据题目,测试用例会提供数据,我们假设输入是合法的。 动态分配的内存由调用者负责释放。 返回值:返回转换后的元素个数(即new_map数组的长度)。 示例: 输入:legacy_map数组,例如: {1, "AEIOULNRST"} {2, "DG"} ... 输出:new_map数组,例如: {'a', 1}, {'e', 1}, ... , {'d',2}, {'g',2}, ... 实现: 先计算总长度,然后分配内存,再填充数据。 注意:每个legacy_map中的keys字符串是以大写字母组成的,且以空字符结尾。 由于题目要求大括号单独一行,我们按照要求格式写代码。 注意:在C语言中,使用tolower函数需要包含<ctype.h>。 编写代码:</think>### 解决方案 ```c #include <ctype.h> #include <stdlib.h> #include <string.h> typedef struct { int value; const char *keys; } legacy_map; typedef struct { char key; int value; } new_map; int convert(const legacy_map *input, const size_t input_len, new_map **output) { // 计算总字母数量 size_t total_chars = 0; for (size_t i = 0; i < input_len; i++) { total_chars += strlen(input[i].keys); } // 分配内存空间 *output = (new_map *)malloc(total_chars * sizeof(new_map)); if (*output == NULL) { return -1; // 内存分配失败 } // 填充新数据结构 size_t index = 0; for (size_t i = 0; i < input_len; i++) { const char *ptr = input[i].keys; while (*ptr != '\0') { // 大写转小写并存储 (*output)[index].key = tolower((unsigned char)*ptr); (*output)[index].value = input[i].value; ptr++; index++; } } return total_chars; // 返回转换后的元素数量 } ``` ### 算法说明 1. **计算总字母数**: - 遍历所有旧版字母组 - 累加每组字符串长度得到总字母数量 2. **内存分配**: - 根据总字母数分配新版映射数组内存 - 检测内存分配失败情况 3. **数据转换**: - 双层循环遍历旧数据结构 - 外层:遍历每个分数组 - 内层:遍历组内每个字母 - 使用`tolower()`转换大小写 4. **返回值**: - 成功时返回转换后的元素总数 - 内存分配失败时返回-1 ### 测试示例 ```c #include <stdio.h> int main() { // 测试数据 legacy_map input[] = { {1, "AEIOULNRST"}, {2, "DG"}, {3, "BCMP"}, {4, "FHVWY"}, {5, "K"}, {8, "JX"}, {10, "QZ"} }; const size_t input_len = sizeof(input) / sizeof(input[0]); new_map *output = NULL; int count = convert(input, input_len, &output); // 验证转换结果 printf("Total letters: %d\n", count); for (int i = 0; i < count; i++) { printf("%c: %d\n", output[i].key, output[i].value); } free(output); // 释放分配的内存 return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值