信息奥赛一本通1225:金银岛

这篇博客探讨了信息奥赛中的一个问题——金银岛。KID在金银岛上面对不同种类、不同重量和价值的金属,需要找到能最大化价值的分割方案。问题描述包括口袋承重限制、金属种类及价值比例,以及输入输出样例。求解策略是找出如何在限定重量下获取最大价值。

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

【题目描述】
某天KID利用飞行器飞到了一个金银岛上,上面有许多珍贵的金属,KID虽然更喜欢各种宝石的艺术品,可是也不拒绝这样珍贵的金属。但是他只带着一个口袋,口袋至多只能装重量为w的物品。岛上金属有s个种类, 每种金属重量不同,分别为n1,n2,…,ns,同时每个种类的金属总的价值也不同,分别为v1,v2,…,vsv1,v2,…,vs。KID想一次带走价值尽可能多的金属,问他最多能带走价值多少的金属。注意到金属是可以被任意分割的,并且金属的价值和其重量成正比。

【输入】
第1行是测试数据的组数k,后面跟着k组输入。

每组测试数据占3行,第1行是一个正整数w(1≤w≤10000),表示口袋承重上限。第2行是一个正整数s(1≤s≤100),表示金属种类。第3行有2s个正整数,分别为n1,v1,n2,v2,…,ns,分别为第一种,第二种,…,第s种金属的总重量和总价值(1≤ni≤10000,1≤vi≤10000)。

【输出】
k行,每行输出对应一个输入。输出应精确到小数点后2位。

【输入样例】
2
50
4
10 100 50 30 7 34 87 100
10000
5
1 43 43 323 35 45 43 54 87 43
【输出样例】
171.93
508.00

//1225:金银岛 
#include<iostream>
#include<cstring>
#include<iomanip>
#include<algorithm>//sort函数用到 
using namespace std;
struct js //定义结构体,金属 
{
	int zl;//重量
	int v;//总价值
	double dj;//单价,每克金属值多少钱 
} a[10001];
int k,w,s,i,j,yw;//yw是已经拿了的金属重量和 
double zj;//zj是已经拿的所有金属的价值和 
bool cmp(js x,js y)
{
	return x.dj>y.dj;
}
int main()
{
	
<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、付费专栏及课程。

余额充值