信息奥赛一本通1212:LETTERS

博客介绍了信息奥赛中的LETTERS问题,内容涉及寻找大写字母矩阵中最多能经过的不同字母个数。输入包括字母矩阵的行数和列数,输出是最多能走过的不同字母数量。解题关键在于找到最长的含有不同字母的连续路径。样例给出了3x6的字母矩阵及解答示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【题目描述】
给出一个roe×colroe×col的大写字母矩阵,一开始的位置为左上角,你可以向上下左右四个方向移动,并且不能移向曾经经过的字母。问最多可以经过几个字母。

【输入】
第一行,输入字母矩阵行数RR和列数SS,1≤R,S≤201≤R,S≤20。

接着输出RR行SS列字母矩阵。

【输出】
最多能走过的不同字母的个数。

【输入样例】
3 6
HFDFFB
AJHGDH
DGAGEH
【输出样例】
6

解题思路:
最后的轨迹必然是有maxn个不同字母连续在一起组成的。
比如样例数据的轨迹如图所示:
在这里插入图片描述

//1212:LETTERS 
#include<iostream>
using namespace std;
int a[27]={0},r,s,i,j,maxn=0;//r:多少行,s:多少列,maxn记录最大值 
char c[21][21];//记录原始矩阵中的字母 
//a[1]=1表示大写字母A已经被走过了,……a[26]表示大写字母Z被走过了
//a[0]记录被走过的不同字母个数 
int x[4]={-1,0,1,0},y[4]={0,1,0,-1};//上、右、下、左 四个方向 
void dfs(int i,int j)//走到第i行、第j列
{
	if(a[c[i][j]-65+1]==0)//连续走过的,必然是不同的大写字母 
	{
		a[c[i][j]-65+1]=1;//标记这个字母被走过了 
		a[0]++;//走过的不同字母数加1
		if(maxn<a[0])
		maxn=a[0];	
	}
	
	int k=a[0];//保存当前a[0]值,即走过了多少个不同字母 
	for(int t=0;t<=3;t++)//朝4个方向继续走
	{
		a[0]=k;//重新取得原来的a[0]值 
<think>我们正在解决信息奥赛一本中的题目:删除单词后缀(题目编号1141)。 题目要求:给定一个单词,如果单词以"er"、"ly"或"ing"结尾,则删除这个后缀(只删除一个后缀,且题目保证删除后单词长度不为0)。 注意:后缀的删除优先级是,如果有多个后缀同时满足,优先删除最长的后缀(即先检查3字符的后缀"ing",再检查2字符的后缀"er"和"ly")。 解题思路: 1. 读取输入的单词。 2. 获取单词长度。 3. 按照优先级检查后缀(先检查3字符的"ing",再检查2字符的"er"和"ly"): - 如果单词长度大于等于3且最后三个字符是"ing",则删除这三个字符(即新字符串长度为原长度减3)。 - 否则,如果单词长度大于等于2且最后两个字符是"er",则删除这两个字符。 - 否则,如果单词长度大于等于2且最后两个字符是"ly",则删除这两个字符。 4. 输出处理后的字符串。 注意:题目只要求删除一个后缀,所以旦匹配到一个后缀并删除,就不再检查其他后缀。 代码实现(C++):</think># 信息奥赛一本 1141:删除单词后缀 解题方法 ## 题目分析 题目要求删除单词的特定后缀(`er`、`ly` 或 `ing`),但只删除一个后缀。关键点在于: 1. **后缀优先级**:优先删除最长的后缀(`ing` > `er`/`ly`) 2. **后缀长度**:`ing` 是3字符后缀,`er` 和 `ly` 是2字符后缀 3. **边界条件**:删除后单词长度不为零 ## 高效解题思路 ### 算法步骤 1. **获取单词长度**:确定字符串长度 `len` 2. **检查后缀优先级**: - 先检查3字符后缀 `ing`(最长后缀优先) - 再检查2字符后缀 `er` - 最后检查2字符后缀 `ly` 3. **调整长度**:匹配到后缀则减少对应长度 4. **输出结果**:截取原始字符串的前 `len` 个字符 ### 时间复杂度 $O(1)$,所有操作都是常数时间操作(后缀检查使用子串截取,最大检查长度固定为3) ## C++ 代码实现 ```cpp #include <iostream> #include <string> using namespace std; int main() { string s; cin >> s; // 读取输入单词 int len = s.size(); // 获取原始长度 // 优先检查并删除最长后缀 "ing"(3字符) if (len >= 3 && s.substr(len-3, 3) == "ing") { len -= 3; // 长度减少3 } // 检查并删除 "er"(2字符) else if (len >= 2 && s.substr(len-2, 2) == "er") { len -= 2; // 长度减少2 } // 检查并删除 "ly"(2字符) else if (len >= 2 && s.substr(len-2, 2) == "ly") { len -= 2; // 长度减少2 } cout << s.substr(0, len) << endl; // 输出处理后的单词 return 0; } ``` ## 关键点解析 1. **后缀检查顺序**:必须按照 `ing` → `er` → `ly` 的顺序检查,确保优先删除最长后缀 2. **边界保护**:每次检查前验证字符串长度(`len >= 2` 或 `len >= 3`)避免越界 3. **子串截取**:使用 `substr(pos, len)` 方法: - `s.substr(len-3, 3)` 获取最后3个字符 - `s.substr(0, len)` 输出处理后的单词 4. **长度调整**:匹配到后缀时修改长度变量 `len`,最后统截取 ## 测试用例验证 | 输入 | 输出 | 说明 | |---------------|------------|--------------------------| | `referer` | `refer` | 删除 `er` 后缀 | | `friendly` | `friend` | 删除 `ly` 后缀 | | `jumping` | `jump` | 删除 `ing` 后缀 | | `ingly` | `ly` | 只删除一个后缀(`ing`) | | `hello` | `hello` | 无匹配后缀 | | `sing` | `s` | 删除 `ing` 后缀 | ## 算法优化 对于性能要求更高的场景,可避免使用 `substr`,直接比较最后几个字符: ```cpp // 优化版本(避免substr开销) if (len >= 3 && s[len-3]=='i' && s[len-2]=='n' && s[len-1]=='g') { len -= 3; } else if (len >= 2 && s[len-2]=='e' && s[len-1]=='r') { len -= 2; } else if (len >= 2 && s[len-2]=='l' && s[len-1]=='y') { len -= 2; } ``` ## 常见错误规避 1. **顺序错误**:若先检查 `er` 再检查 `inger`,会导致错误删除部分后缀 2. **长度检查缺失**:未检查 `len >= 3` 直接取最后3字符会导致运行时错误 3. **多次删除**:题目要求只删除一个后缀,无需循环处理 > 本题考察字符串基础操作和条件判断逻辑,是信息奥赛中典型的字符串处理入门题[^1]。 [^1]:信息奥赛一本》字符串处理专题解析,详见 [ybt 题解精要](https://oi-wiki.org/string/)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

mengdicfm

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

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

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

打赏作者

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

抵扣说明:

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

余额充值