信息学奥赛一本通 1194:移动路线 (耙耙)

本文介绍了一个使用动态规划解决从左上角到右下角路径计数问题的算法。通过初始化边界条件,递归地计算每个网格节点到达目标点的路径数量。最终,算法返回从起点到终点的所有可能路径总数。

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

http://ybt.ssoier.cn:8088/problem_show.php?pid=1194
在这里插入图片描述

从左下走到右上
转换成 从 左上走到右下

注意最好用 long long 尽管这题没有用到long long

#include<bits/stdc++.h>
using namespace std;
long long  a[105][105];
long long  m,n;
void print(){
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++){
			cout<<a[i][j]<< " ";
		}
		cout<<endl;
	}
	cout<<endl;
}
int main(){
//	freopen("cpp.in","r",stdin);
//	freopen("cpp.out","w",stdout);
	cin>>m>>n;
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++){
			if(i==1||j==1){
				a[i][j] = 1;
			}else{
				a[i][j] = a[i-1][j] + a[i][j-1];
			}
		}
	}
//	print();
	cout<<a[m][n]<<endl;
	return 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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值