pat甲级刷题计划-字符串

PAT甲级刷题计划-字符串

字符串整理的共19题(持续整理中),后续会整理相应的题号。题目参考自acwing
~,争取在8月份前完成更新!

目录

  • 1.计算 a+b
  • 2.拼写正确
  • 3.签到与签出
  • 4.密码
  • 5.男孩vs女孩
  • 6.字符串减法
  • 7.说法方式
  • 8.约会(1061)

1.计算 a+b

并以标准格式输出总和----也就是说,从最低位开始每隔三位数加进一个逗号(千位分隔符),如果结果少于四位则不需添加。
输入格式

共一行,包含两个整数 a和 b。

输出格式

共一行,以标准格式输出 a+b的和。

数据范围

  − 1 0 6 ≤ a , b ≤ 1 0 6 \ −10^6 ≤a,b≤ 10^6  106a,b106

输入样例:

-1000000 9

输出样例:

-999,991

#include 
#include 
#include 
#include 

using namespace std;

int main()
{
    int a,b;
    cin>>a>>b;
    int c = a+b;
    string s = to_string(abs(c)),res;//方便后续添加‘-’号
    for(int i=s.size()-1,j=0;i>=0;i--,j++)
    {
        if(j%3==0&&j) res = ','+res;//每经过三个就加一个‘,’且开头不加
        res = s[i]+res;
    }
    if(c<0) res = '-'+res;
    cout<<res;
    return 0;
}

2.拼写正确

给定一个非负整数 N,你的任务是计算 N的所有数字的总和,并以英语输出总和的每个数字。

输入格式
共一行,包含一个整数 N。

输出格式
共一行,用英语输出总和的每个数字,单词之间用空格隔开。

数据范围

  0 ≤ N ≤ 1 0 100 \ 0≤N≤10^{100}  0N10100

输入样例:

12345

输出样例:

one five

#include 
#include 
#include 
#include 
using namespace std;

string word[] = {"zero","one","two","three","four","five","six","seven","eight","nine"};//映射到一个字母表中

int main()
{
    string s;
    cin>>s;
    int t = 0;
    for(int i =0; i<s.size();i++)
        t+=s[i]-'0';
    string res = to_string(t);
    
    for(int i =0; i<res.size();i++)
        cout<<word[res[i]-'0']<<" ";
    
    return 0;
}

3.签到与签出

每天第一个到机房的人负责开门,最后一个从机房离开的人负责锁门。

现在,给定每个人的签到与签出记录,请你找出当天开门的人以及锁门的人分别是谁。

输入格式

第一行包含整数 M,表示共有 M个人的签到签出记录。

接下来 M行,每行的形式如下:

ID_number Sign_in_time Sign_out_time

时间以 HH:MM:SS 形式给出,ID_number 是一个长度不超过 15的字符串。

输出格式

共一行,输出开门人和锁门人的ID_number,用一个空格隔开。
数据范围

1 ≤ M ≤ 10 1≤M≤10 1M10

数据保证每个人的签到时间早于签出时间,并且不会出现两个人同时签到或同时签出的情况。

输入样例:

3
CS301111 15:30:28 17:00:10
SC3021234 08:00:00 11:25:25
CS301133 21:45:00 21:58:40

输出样例:

SC3021234 CS301133

#include 
#include 
#include 

using namespace std;

int n;

string in_id,out_id,in_time,out_time;

int main()
{
//因为字典序的原因可以直接比大小(由于都在同一天内)
    cin>>n;
    
    cin>>in_id>>in_time>>out_time;
    
    out_id = in_id;
    
    for (int i = 1; i < n; i ++ )
    {
        string id,in,out;
        cin>>id>>in>>out;
        
        if(in<in_time) in_id = id,in_time = in;
        if(out>out_time) out_id = id,out_time = out;
        
    }
    cout<<in_id<<" "<<out_id;
    return 0;
}

4.密码

为了准备 PAT,系统不得不为用户生成随机密码。

但是有时一些数字和字母之间总是难以区分,比如 1(数字一)和 l(L的小写),0(数字零)和 O(o的大写)。

一种解决办法是将 1(数字一)替换为 @,将 0(数字零)替换为 %,将 l(L的小写)替换为 L,将 O(o的大写)替换为 o。

现在,你的任务就是帮助系统检查这些用户的密码,并对难以区分的部分加以修改。

输入格式

第一行包含一个整数 N,表示用户数量。

接下来 N行,每行包含一个用户名和一个密码,都是长度不超过 10且不含空格的字符串。

输出格式

首先输出一个整数 M,表示已修改的用户密码数量。

接下来 M行,每行输出一个用户名称和其修改后的密码。

用户的输出顺序和读入顺序必须相同。

如果没有用户的密码被修改,则输出 There are N accounts and no account is modified,其中 N是用户总数。

如果 N=1,则应该输出 There is 1 account and no account is modified。
数据范围

  1 ≤ N ≤ 1000 \ 1≤N≤1000  1N1000

输入样例1:

3
Team000002 Rlsp0dfa
Team000003 perfectpwd
Team000001 R1spOdfa

输出样例1:

2
Team000002 RLsp%dfa
Team000001 R@spodfa

输入样例2:

1
team110 abcdefg332

输出样例2:

There is 1 account and no account is modified

输入样例3:

2
team110 abcdefg222
team220 abcdefg333

输出样例3:

There are 2 accounts and no account is modified

#include
#include
#include 

using namespace std;

string name[1000],pwd[1000];

int main()
{
    unordered_map<char,char> s;
    s['1'] = '@';
    s['0'] = '%';
    s['l'] = 'L';
    s['O'] = 'o';

    
    int n;
    cin>>n;
    int cnt = 0;
    

    for(int i = 0; i<n; i++)
    {
        bool sign = 0;
        string id,word;
        cin>>id>>word;
        for(auto &t:word)
        {
            if(s.count(t)) sign = 1,t = s[t];
        }
        
        if(sign) name[cnt] = id,pwd[cnt++] = word;
    }

    if(!cnt)
    {
        if(n==1) cout<<"There is 1 account and no account is modified";
        else printf("There are %d accounts and no account is modified",n);
    }
    else
    {
        cout<<cnt<<endl;
        for (int i = 0; i < cnt; i ++ )
        {
            cout<<name[i]<<" "<<pwd[i]<<endl;
        }
    }
    
    return 0;
}

5.男孩 vs 女孩

给定 N个学生的成绩信息,请你求出女生第一名与男生倒数第一名的分数差距。 **输入格式** 第一行输入整数 N,表示学生数量。

接下来 N行,每行包含一个学生的姓名,性别,ID和成绩。其中姓名和ID长度不超过 10 且不包含空格的字符串。性别为 F(女)或 M(男)。成绩是一个范围在 [0,100]的整数。保证所有学生的成绩互不相同。

输出格式

输出共三行。

第一行输出女生第一名的姓名和ID。
第二行输出男生倒数第一名的姓名和ID。
第三行输出女生第一名的成绩减去男生倒数第一名的成绩的差。
如果不存在某个性别的学生,则在对应行输出 Absent。
在第三行输出 NA。

数据范围

  1 ≤ N ≤ 101 \ 1≤N≤101  1N101

输入样例1:

3
Joe M Math990112 89
Mike M CS991301 100
Mary F EE990830 95

输出样例1:

Mary EE990830
Joe Math990112
6

输入样例2:

1
Jean M AA980920 60

输出样例2:

Absent
Jean AA980920
NA

#include 
#include 
#include 
#include

using namespace std;

string name,sex,id;

int grade,fg=-1,lg=101;//最高分数,最低分数

string first,last,fn,ln;//最高分ID,最低分ID,最高分名字,最低分名字

int main()
{
    int n;
    cin>>n;
    for (int i = 0; i < n; i ++ )
    {
        cin>>name>>sex>>id>>grade;
        
        if(sex=="M")//男性
        {
            if(grade<lg) last=id,ln=name,lg=grade;
        }
        else
        {
            if(grade>fg) first=id,fn=name,fg=grade;
        }
    }
    
    if(fg<0) cout<<"Absent"<<endl;
    else cout<<fn<<" "<<first<<endl;
    if(lg>100) cout<<"Absent"<<endl;
    else cout<<ln<<" "<<last<<endl;
    
    if(fg<0||lg>100) cout<<"NA"<<endl;
    else cout<<fg-lg<<endl;
    
    
    return 0;
}

6.字符串减法

给定两个字符串 S1 和 S2,S=S1−S2 定义为将 S1 中包含的所有在 S2

中出现过的字符删除后得到的字符串。

你的任务就是计算 S1−S2。

输入格式

共两行,第一行包含字符串 S1,第二行包含字符串 S2。

输出格式

输出共一行,表示 S1−S2的结果。

数据范围

两个给定字符串的长度都不超过 104。

输入样例:

They are students.
aeiou

输出样例:

Thy r stdnts.

#include
#include
#include 

using namespace std;


int main()
{
    string s1,s2;
    getline(cin,s1);
    getline(cin,s2);


    unordered_set<char> hash;
    string res;
    for(auto t:s2) hash.insert(t); 

    for(auto t:s1) if(!hash.count(t)) res+=t;
    cout<<res;
    return 0;
}

7.说法方式

不同的人对描述同一种事物的同义词的偏爱程度可能不同。

例如,在说警察时,有人喜欢用 the police,有人喜欢用 the cops。

分析说话方式有助于确定说话者的身份,这在验证诸如和你线上聊天的是否
是同一个人十分有用。

现在,给定一段从某人讲话中提取的文字,你能确定他的最常用词吗?

输入格式
输入共一行,包含一个字符串,以回车符 \n 终止。

输出格式
共一行,输出最常用词以及其出现次数。

如果常用词有多个,则输出字典序最小的那个单词。

注意,单词在输出时,必须全部小写。

单词是指由连续的字母和数字构成的,被非字母数字字符或行首/行尾分隔开的,连续序列。

单词不区分大小写。

数据范围

输入字符串长度不超过 1048576,且至少包含一个大小写字母或数字。

输入样例:

Can1: “Can a can can a can? It can!”

输出样例:

can 5

#include
#include
#include 

using namespace std;

bool check(char c)
{
    if(c>='0'&&c<='9'||c>='a'&&c<='z'||c>='A'&&c<='Z') return true;
    return false;
}

int main()
{
    unordered_map<string,int> m;//记录出现最多的单词
    string s;
    getline(cin,s);
    
    for(int i=0,j=0;i<s.size();i++)
    {
        if(check(s[i]))
        {
            string word;
            word+=tolower(s[i]);
            j=i+1;
            while(check(s[j])) word+=tolower(s[j]),j++;
            m[word]++;
            i=j-1;
        }

    }
    
    int cnt=-1;
    string res;
    
    for(auto t:m)
        if(t.second>cnt||(t.second==cnt&&t.first<res)) res = t.first,cnt = t.second;
    
    cout<<res<<" "<<cnt;
    return 0;
}

8.约会

大侦探福尔摩斯接到一张奇怪的字条:

我们约会吧!
3485djDkxh4hhGE
2984akDfkkkkggEdsb
s&hgsfdk
d&Hyscvnm

大侦探很快就明白了,字条上奇怪的乱码实际上就是约会的时间星期四 14:04,因为前面两字符串中第 1对相同大写英文字母(大小写有区分)是第 4 个字母 D,代表星期四;第 2 对相同的字符是 E ,那是第 5 个英文字母,代表一天里的第 14 个钟头(于是一天的 0 点到 23 点由数字 0 到 9、以及大写字母 A 到 N 表示);后面两字符串第 1 对相同英文字母 s 出现在第 4 个位置(从 0 开始计数)上,代表第 4分钟。

现给定两对字符串,请帮助福尔摩斯解码得到约会的时间。
补充

1、一对字符相同,是指在两个字符相同且在字符串的位置也相同。
2、前两个字符串中第一对相同的大写英文字母,是指第一对能够正确代表日期的大写英文字母。
3、前两个字符串中第二对相同的字符,是指位于代表日期的字符后面的,第一对相同的,能够正确代表小时的字符。

输入格式
输入在 4行中分别给出 4 个非空、不包含空格、且长度不超过 60的字符串。

输出格式

在一行中输出约会的时间,格式为 DAY HH:MM,其中 DAY 是某星期的 3
字符缩写,即 MON 表示星期一,TUE 表示星期二,WED 表示星三,THU 表示星期四,FRI 表示星期五,SAT 表示星期六,SUN 表示星期日。

题目输入保证每个测试存在唯一解。

输入样例:

3485djDkxh4hhGE
2984akDfkkkkggEdsb
s&hgsfdk
d&Hyscvnm

输出样例:

THU 14:04

#include
#include

using namespace std;

string week[7] = {"MON","TUE","WED","THU","FRI","SAT","SUN"};

int main()
{
    string a,b,c,d;
    cin>>a>>b>>c>>d;
    
    int k=0;
    for (int i = 0; i < a.size()&&b.size(); i ++ )
    {
        if(a[i]==b[i]&&a[i]>='A'&&a[i]<='G'){ k = i;break;}
    }
    cout<<week[a[k]-'A']<<" ";
    k++;
    
    for(;k<a.size()&&b.size();k++)
    {
        if(a[k]==b[k]&&(a[k]>='0'&&a[k]<='9'||a[k]>='A'&&a[k]<='N')){break;}
    }
    printf("%02d:",a[k]<='9'?a[k]-'0':a[k]-'A'+10);
    
    k=0;
    for(;k<c.size()&&d.size();k++)
    {
        if(c[k]==d[k]&&(c[k]>='a'&&c[k]<='z'||c[k]>='A'&&c[k]<='Z'))break;
    }
    printf("%02d",k);
    return 0;
}

你可能感兴趣的:(PTA,c++,算法,c语言)