练习算法程序设计题——新手篇(2)
这次记录主要是想要回忆起字符串的题型从码蹄杯里面以及洛谷里面找的题来进行的练习。MC0504伐楚是好时机公子光在暗中观察吴王僚与大臣们商讨攻打楚国的事宜。他心中盘算只要吴王亲自带兵出征宫中的守卫就会减少这正是行动的大好机会。为了模拟守卫的变化公子光使用了一个特殊装置装置上有27个按键分别对应小写英文字母a-z和删除键D。当按下小写字母按键时会在序列末尾添加一个对应的字符当按下删除键D时则会删除序列末尾的一个字符如果序列为空则忽略。现在给定一个字符串s表示公子光的按键操作序列请输出操作结束后序列中的字符。如果序列为空则输出一行字符串!!!!表示宫中已无守卫时机成熟。格式输入格式一行一个长度不超过1e6的字符串s。输出格式一行一个字符串表示答案。样例输入abcD输出ab本题相关知识点 语言基础字符串思考先记录一下自己的错误想法一开始见到这个题自己就想着直接就用D来覆盖掉前面一个位置的小写字母s[i-1]D然后输出时就来跳过D输出。但是这样看似可以通过部分示例可当D在第一个位置时就会出数组或者说是字符串访问过界的情况。并且该题目的原意是想要删掉D之前的小写字母这样覆盖的话实则并没有满足题意尽管输出可能看似正确但是判题时仍然会给到WA。所以换一种思路假定我们在遍历访问字符串时遇到D我们就将前一个字符删除也就是弹出这样一来的话我们是否就能想到一个数据存储结构——栈pop弹出push推入栈顶。但是我们需要考虑到一个问题如果将字符存入栈中的话栈是先进后出的输出时我们是只能输出栈顶元素就会导致逆序输出如果将栈里面的数据翻转的话又很麻烦。再换一下思路我们用我们熟悉的字符串来模拟栈就可以解决了。代码如下#include bits/stdc.h using namespace std; int main(){ string s, ans; // s是输入的字符串ans用于存放答案的字符串 cin s; int len s.length(); for(int i 0; i len; i) { if(s[i] D) // 若是检测到D就进行删除操作 { if(!ans.empty()) ans.pop_back(); // 这里的条件一定明白当存放答案的ans非空才能进行弹出“栈”的操作 } else ans s[i]; // 若不是D则将字符存入ans中 } if(ans.empty()) cout !!!!; else cout ans; return 0; }注意字符串模拟栈时就弹出的函数是不一样的stack是用的pop()而字符串里面则是使用的pop_back()。P5733 【深基6.例1】自动修正时间限制: 1.00s 内存限制: 128.00MB大家都知道一些办公软件有自动将字母转换为大写的功能。输入一个长度不超过 100 且不包括空格的字符串。要求将该字符串中的所有小写字母变成大写字母并输出。格式输入格式输入一行一个字符串。输出格式输出一个字符串即将原字符串中的所有小写字母转化为大写字母。样例输入Luogu4!输出LUOGU4!思考这个题一看到我就想到了ASCII的加减转换大小写字母但是其实有一个非常简单的做法就是直接使用toupper(c)将小写字母转换为大写tolower(c)将大写字母转换为小写新手练习的话还是要明白原理更好所以就直接用的ASCII进行加减来转换了。代码如下#include bits/stdc.h using namespace std; int main(){ string s, ans; cin s; int len s.length(); for(int i 0; i len; i) { if(s[i]a s[i]z) { s[i] - 32; } ans s[i]; } cout ans; return 0; }说明这里一开始我也不知道大小写字母ASCII码相差多少然后自己输出了(int)A和(int)a分别得到65和97因此相差32故代码里面小写字母的ASCII码就是直接减32得大写字母的ASCII码。P1914 小书童——凯撒密码时间限制: 1.00s 内存限制: 512.00MB某蒟蒻迷上了 “小书童”有一天登陆时忘记密码了他没绑定邮箱 or 手机于是便把问题抛给了神犇你。蒟蒻虽然忘记密码但他还记得密码是由一个字符串组成。密码是由原文字符串由不超过 50 个小写字母组成中每个字母向后移动 n 位形成的。z的下一个字母是a如此循环。他现在找到了移动前的原文字符串及 n请你求出密码。格式输入格式第一行n。第二行未移动前的一串字母。输出格式一行是此蒟蒻的密码。样例输入1 qwe输出rxf#include bits/stdc.h using namespace std; int main(){ int n; string s; cin n s; int len s.length(); for(int i 0; i len; i) { int num1 s[i] - a; // 直接使用字符减去a得到当前字符在26个字母里面的排序(注意这里的a相当于是第0个) int num2 num1 n; int modn num2 % 26; s[i] a modn; } cout s; return 0; }P1125 [NOIP 2008 提高组] 笨小猴时间限制: 1.00s 内存限制: 125.00MB笨小猴的词汇量很小所以每次做英语选择题的时候都很头疼。但是他找到了一种方法经试验证明用这种方法去选择选项的时候选对的几率非常大这种方法的具体描述如下假设 maxn 是单词中出现次数最多的字母的出现次数minn 是单词中出现次数最少的字母的出现次数如果 maxn−minn 是一个质数那么笨小猴就认为这是个 Lucky Word这样的单词很可能就是正确的答案。格式输入格式一个单词其中只可能出现小写字母并且长度小于 100。输出格式共两行第一行是一个字符串假设输入的单词是 Lucky Word那么输出Lucky Word否则输出No Answer第二行是一个整数如果输入的单词是 Lucky Word输出 maxn−minn 的值否则输出 0。样例输入 #1error输出 #1Lucky Word 2输入 #2olympic输出 #2No Answer 0说明/提示【输入输出样例 1 解释】单词error中出现最多的字母 r 出现了 3 次出现次数最少的字母出现了 1 次3−122 是质数。【输入输出样例 2 解释】单词olympic中出现最多的字母 i 出现了 1 次出现次数最少的字母出现了 1 次1−100 不是质数。本处原题面错误已经修正思考这个题不算难但是对于最多出现次数的字母与出现次数最少的字母的统计的话就会有一个陷阱在于出现的最少次数不能是0所以这里在对于识别到出现次数为0的字母就会直接continue跳过另一个点就是质数的判断这个原理我说不清楚但是之前就是一直写的循环从2开始遍历直到被判断数开根号的数(sqrt(x))处如果中间没有一个数字可以被整除则说明这个数是质数反之只要有一个数被整除了就直接返回false。#include bits/stdc.h using namespace std; int a[26]; bool is_pri(int x) { if(x0 || x1) return false; for(int i 2; i*i x; i) { if(x%i 0) return false; } return true; } int main(){ string s; cin s; int len s.length(); for(int i 0; i len; i) { a[s[i]-a]; } int maxn 0, minn 1000; for(int i 0; i 26; i) { if(a[i] 0) continue; if(a[i] maxn) maxn a[i]; if(a[i] minn) minn a[i]; } int temp maxn - minn; if(is_pri(temp)) cout Lucky Word\n temp; else cout No Answer\n 0; return 0; }P5015 [NOIP 2018 普及组] 标题统计时间限制: 1.00s 内存限制: 256.00MB凯凯刚写了一篇美妙的作文请问这篇作文的标题中有多少个字符 注意标题中可能包含大、小写英文字母、数字字符、空格和换行符。统计标题字符数时空格和换行符不计算在内。格式输入格式输入文件只有一行一个字符串 s。输出格式输出文件只有一行包含一个整数即作文标题的字符数不含空格和换行符。样例输入 #1234输出 #13输入 #2Ca 45输出 #24说明/提示样例 1 说明标题中共有 3 个字符这 3 个字符都是数字字符。样例 2 说明标题中共有 5 个字符包括 1 个大写英文字母 1 个小写英文字母和 2 个数字字符 还有 1 个空格。由于空格不计入结果中故标题的有效字符数为 4 个。数据规模与约定规定 ∣s∣ 表示字符串 s 的长度即字符串中的字符和空格数。对于 40% 的数据1≤∣s∣≤5保证输入为数字字符及行末换行符。对于 80% 的数据1≤∣s∣≤5输入只可能包含大、小写英文字母、数字字符及行末换行符。对于 100% 的数据1≤∣s∣≤5输入可能包含大、小写英文字母、数字字符、空格和行末换行符。思考这个题本身是不难的就是做一个字符的统计如果是空格或者换行符就跳过就行。但是关键在于字符串的输入。这里我将会对字符串的输入做一个小小的总结在C里面如果直接使用cin的话是读不到字符串里面的空格和换行符的如果想要读空格就需要使用getline来输入getline(cin, s)这样输入进去的字符串是带着空格的如果想要将空格和换行符都读进一个字符串那么就需要使用getcharwhile((cgetchar())!EOF)则是将每一个字符都给读到了下面的代码里面展示了存储字符串。#include bits/stdc.h using namespace std; int main(){ char c; string s; while((cgetchar())!EOF) s c; //主要就是要注意输入 int len s.length(), ans 0; for(int i 0; i len; i) { if(s[i] || s[i]\n) continue; ans; } cout ans; return 0; }今天就先记录这么些题这两天先把字符串给掌握了吧冲冲冲