其他分享
首页 > 其他分享> > 洛谷字符串题解

洛谷字符串题解

作者:互联网

昨天做了7题,赶脚不错哦,但总体来说洛谷上字符串的题还是很水的 二3二,

在看题解前先总结几个关于字符串的小方法:
1.~~~(变量).size() 

用来统计这个字符串变量中字符的个数

2.~~~(变量).find()

用来寻找一个字符串中的一个子串开头字母的位置(默认从0开始寻找)

3.~~~(变量).substr()

用来截取一个字符串中的一个子串

第一个参数是开始寻找的位置,第二个参数是子串长度

例如:输入的字符串为abcde,输入到s变量里(cin>>s),

所以如果进行s.substr(2,3)操作,最后就会输出bcd

小方法说完了,那就来看看今天的题解吧 :) :)

Q1:自动修正

题目描述

大家都知道一些办公软件有自动将字母转换为大写的功能。输入一个长度不超过 100 且不包括空格的字符串。要求将该字符串中的所有小写字母变成大写字母并输出。

这是一道很水的题目,我长话短说

简析这个题目,其实就是先判断输入字符的大小写,再将小写变为大写即可

上代码!

#include<iostream>
using namespace std;
int main(){
    string s;
    cin>>s;
    for(int i=0;i<s.size();i++)
    {
        if(s[i]>='a'&&s[i]<='z')
        s[i]=s[i]-32;//利用ask码转换字母的大小写
    }
    cout<<s;
}

话不多说,看第二道水题

Q2:小书童——凯撒密码

题目背景

某蒟蒻迷上了“小书童”,有一天登陆时忘记密码了(他没绑定邮箱or手机),于是便把问题抛给了神犇你。

题目描述

蒟蒻虽然忘记密码,但他还记得密码是由一个字符串组成。密码是由原文字符串(由不超过 50 个小写字母组成)中每个字母向后移动 n 位形成的。z 的下一个字母是 a,如此循环。他现在找到了移动前的原文字符串及 n,请你求出密码。

输入格式

第一行:n。第二行:未移动前的一串字母

输出格式

一行,是此蒟蒻的密码

其实这一题的唯一待结点是,如果在移动n位置后由z+n转换到了a甚至还往后,那么就要重新计算,使z的下一位是a

上代码!

#include<iostream>
using namespace std;
int main(){
    int n;
    cin>>n;
    string s;
    cin>>s;
    for(int i=0;i<s.size();i++)
    {
        if(s[i]+n<='z')
        s[i]=s[i]+n;
        //判断其是否涉及到了由z到a的过程
        else
        s[i]=s[i]+n-26;
        //如果牵涉到了,就讲z的下一位设置为a
    }
    cout<<s;
}

Q3:标题统计

题目描述

凯凯刚写了一篇美妙的作文,请问这篇作文的标题中有多少个字符? 注意:标题中可能包含大、小写英文字母、数字字符、空格和换行符。统计标题字 符数时,空格和换行符不计算在内。

输入格式

输入文件只有一行,一个字符串 ss。

输出格式

输出文件只有一行,包含一个整数,即作文标题的字符数(不含空格和换行符)。

这题我已经不想多说什么了,前面只要看懂s.size()用法的同志们都应该会,for循环计数就ok

上代码!

#include<iostream>
using namespace std;
int main(){
    string s;
    int sum=0;
    while(cin>>s)
    {
        sum+=s.size();
    }
    cout<<sum<<endl;
}

Q4:手机

题目描述

一般的手机的键盘是这样的:

要按出英文字母就必须要按数字键多下。例如要按出 x 就得按 9 两下,第一下会出 w,而第二下会把 w 变成 x。0 键按一下会出一个空格。

你的任务是读取若干句只包含英文小写字母和空格的句子,求出要在手机上打出这个句子至少需要按多少下键盘。

输入格式

一行句子,只包含英文小写字母和空格,且不超过 200 个字符。

输出格式

一行一个整数,表示按键盘的总次数。

 这道题和前面的题有所不同,要统计按键的次数,仔细思考就会发现每一个字母按动次数是固定的,并且和它的次序有关。如果讲这些数据存入一个数组中,那么只要求出每一个数字的位置,那么将按动次数与位置联系起来,这道题就完成了

上代码!

#include<iostream>
using namespace std;
int cnt[26]={1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,1,2,3,1,2,3,4};
int main(){
   string s;
   getline(cin,s);
   int sum=0;
   for(int i=0;i<s.size();i++)
   {
       if(s[i]==' ')
       sum++;
       //如果输入的是空格,那么按键次数直接+1
       else if(s[i]>='a'&&s[i]<='z')
       sum+=cnt[s[i]-'a'];
       //因为输入的都是小写,所以输入的数在数组中的位置就是离小写字母a的距离(即s[i]-'a')
   }
   cout<<sum;
}

Q5:honoka的键盘

题目背景

honoka 有一个只有两个键的键盘。

题目描述

一天,她打出了一个只有这两个字符的字符串。当这个字符串里含有 VK 这个字符串的时候,honoka 就特别喜欢这个字符串。所以,她想改变至多一个字符(或者不做任何改变)来最大化这个字符串内 VK 出现的次数。给出原来的字符串,请计算她最多能使这个字符串内出现多少次 VK(只有当 V 和 K 正好相邻时,我们认为出现了 VK。)

输入格式

第一行给出一个数字 nn,代表字符串的长度。

第二行给出一个字符串 ss。

输出格式

第一行输出一个整数代表所求答案。

我们分析一下发现,这个题其实就是要求在输入的字符串中求子串VK的出现次数,但他又要求在可以改一个字符的情况下(可以不改),字符串中所含有VK的最多次数,我们可以写一个函数来计算VK的出现次数,再在main函数中添加v,k求改与不改的最大值即可

废话少说,上代码!

#include<iostream>
using namespace std;
int cnt(string s)
{
    int p=s.find("VK");
    int sum=0;
    while(p!=-1)
    {
        sum++;
        p=s.find("VK",p+1);//字符用单引号,字符串用双引号
    }
    return sum;
}
int main(){
    int n;
    cin>>n;
    string s;
    cin>>s;
    int ans=cnt(s);
    for(int i=0;i<s.size();i++)
    {
        string t=s;
        t[i]='V';
        ans=max(ans,cnt(t));
        t[i]='K';
        ans=max(ans,cnt(t));
    }
    cout<<ans<<endl;
}

Q6:单词覆盖还原

题目描述

一个长度为 l(3≤l≤255) 的字符串中被反复贴有 boy 和 girl 两单词,后贴上的可能覆盖已贴上的单词(没有被覆盖的用句点表示),最终每个单词至少有一个字符没有被覆盖。问贴有几个 boy 几个 girl?

输入格式

一行被被反复贴有boy和girl两单词的字符串。

输出格式

两行,两个整数。第一行为boy的个数,第二行为girl的个数。

这道题的输入样例是这样的:

......boyogirlyy......girl.......

其实前面的.......我们可以完全忽略不管,但因为单词被覆盖掉了,这就意味着只要出现一个y,就有一个单词boy,我们把它记录在一个数组里,一个y就把他的前面第2位标记为1,在统计数组中一的数量就可以求出boy和girl的出现总数。根据这个定理能写出这样一段代码:
 

#include <iostream>
using namespace std;
int cnt[300];
int ans[300];
int main(){
    string s;
    cin>>s;
    for(int i=0;i<s.size();i++)
    {
        if(s[i]=='b')
        cnt[i]=1;
        else if(s[i]=='o')
        cnt[i-1]=1;
        else if(s[i]=='y')
        cnt[i-2]=1;
        
        if(s[i]=='g')
        ans[i]=1;
        else if(s[i]=='i')
        ans[i-1]=1;
        else if(s[i]=='r')
        ans[i-2]=1;
        else if(s[i]=='l')
        ans[i-3]=1;
    }
    int sum=0,k=0;
    for(int i=0;i<s.size();i++)
    {
        if(cnt[i]==1)
        sum++;
        if(ans[i]==1)
        k++;
    }
    cout<<sum<<endl<<k;
}

Q7:你的飞碟在这儿

题目描述

众所周知,在每一个彗星后都有一只UFO。这些UFO时常来收集地球上的忠诚支持者。不幸的是,他们的飞碟每次出行都只能带上一组支持者。因此,他们要用一种聪明的方案让这些小组提前知道谁会被彗星带走。他们为每个彗星起了一个名字,通过这些名字来决定这个小组是不是被带走的那个特定的小组(你认为是谁给这些彗星取的名字呢?)。关于如何搭配的细节会在下面告诉你;你的任务是写一个程序,通过小组名和彗星名来决定这个小组是否能被那颗彗星后面的UFO带走。

小组名和彗星名都以下列方式转换成一个数字:最终的数字就是名字中所有字母的积,其中AA是11,ZZ是2626。例如,USACOUSACO小组就是21 \times 19 \times 1 \times 3 \times 15=1795521×19×1×3×15=17955。如果小组的数字\bmod 47mod47等于彗星的数字\bmod 47mod47,你就得告诉这个小组需要准备好被带走!(记住“a \bmod bamodb”是aa除以bb的余数;34 \bmod 1034mod10等于44)

写出一个程序,读入彗星名和小组名并算出用上面的方案能否将两个名字搭配起来,如果能搭配,就输出“GO”,否则输出“STAY”。小组名和彗星名均是没有空格或标点的一串大写字母(不超过66个字母)。

输入格式

第1行:一个长度为1到6的大写字母串,表示彗星的名字。

第2行:一个长度为1到6的大写字母串,表示队伍的名字。

输出格式

这道题看起来题目长,但是实际操作起来还是很简单的。先分解输入的这个字符串,将他们转换为1-26的数字,再分别%47,判断是否相等就可以解决了

上代码!

#include <iostream>
using namespace std;
int main(){
    string s,t;
    cin>>s>>t;
    int sum1=1,sum2=1;
    for(int i=0;i<s.size();i++)
    {
        sum1=sum1*(s[i]-'A'+1)%47;
    }
    for(int i=0;i<t.size();i++)
    {
        sum2=sum2*(t[i]-'A'+1)%47;
    }
    if(sum1==sum2)
    cout<<"GO"<<endl;
    else
    cout<<"STAY"<<endl;
}

又是一个漫长的整理时光~~~

熬夜写得,大家请多指教吧QAQ~·~

标签:洛谷,int,题解,VK,cin,一个,字符串,格式
来源: https://blog.csdn.net/jiayi20090626/article/details/122689279