天梯赛练习集 L1 20分题(持续更新)

最近在准备天梯赛,所以准备把20分题写一遍

L1 -006 连续因子

一个正整数 N 的因子中可能存在若干连续的数字。例如 630 可以分解为 3×5×6×7,其中 5、6、7 就是 3 个连续的数字。给定任一正整数 N,要求编写程序求出最长连续因子的个数,并输出最小的连续因子序列。

输入格式:

输入在一行中给出一个正整数 N(1<N<231)。

输出格式:

首先在第 1 行输出最长连续因子的个数;然后在第 2 行中按 因子1*因子2*……*因子k 的格式输出最小的连续因子序列,其中因子按递增顺序输出,1 不算在内。

代码 

#include <iostream>
#include <vector>

using namespace std;

vector<int>qus,ans;

void find_number(int n){
     for(int i=2;i<=n/i;i++){
         if(n%i==0){
             int m=n;
             int j=i;
             while(m%j==0){
                 ans.push_back(j);
                 m/=j;
                 j++;
             }
         }
         if(ans.size()>qus.size())qus=ans;
         ans.clear();
     }
     if(qus.empty())qus.push_back(n);
}

int main(){
    int n;
    cin>>n;

    find_number(n);

    if(!qus.empty()){
        cout<<qus.size()<<endl;
        cout<<qus[0];
        for(int i=1;i<qus.size();i++)cout<<'*'<<qus[i];
    }
}

L1-009 N个数求和

本题的要求很简单,就是求N个数字的和。麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式。

输入格式:

输入第一行给出一个正整数N(≤100)。随后一行按格式a1/b1 a2/b2 ...给出N个有理数。题目保证所有分子和分母都在长整型范围内。另外,负数的符号一定出现在分子前面。

输出格式:

输出上述数字和的最简形式 —— 即将结果写成整数部分 分数部分,其中分数部分写成分子/分母,要求分子小于分母,且它们没有公因子。如果结果的整数部分为0,则只输出分数部分。

输入样例1:

5
2/5 4/15 1/30 -2/60 8/3

输出样例1:

3 1/3

代码 

//gcd最大公约数
//25.3.14

#include <iostream>
#include <algorithm>
#include <sstream>
#include <cstdio>

using namespace std;

typedef long long LL;

const int N = 110;

struct Node{
    LL a,b;
}cp[N];

LL gcd(LL a,LL b){
    return b ? gcd(b,a % b) : a;
}

int main(){
    int n;
    cin >> n;

    LL mul = 1;
    for(int i = 0;i < n;i ++){
        string line;
        cin >> line;
        
        LL a,b;
        sscanf(line.c_str(),"%lld/%lld",&a,&b);
        cp[i] = {a,b};
        
        mul *= cp[i].b;
    }

    LL sum = 0;
    for(int i = 0;i < n;i ++)sum += cp[i].a * (mul / cp[i].b);
    
    if(sum != 0){
        LL d = gcd(sum,mul);
        sum /= d,mul /= d;
    }

    LL res = sum / mul,r = sum % mul;

    if(!r)cout << res;
    else{
        if(!res)cout << r <<'/' << mul;
        else cout <<res <<' ' << r << '/' << mul;
    }

    return 0;
}

 L1-011 A-B

本题要求你计算A−B。不过麻烦的是,A和B都是字符串 —— 即从字符串A中把字符串B所包含的字符全删掉,剩下的字符组成的就是字符串A−B。

输入格式:

输入在2行中先后给出字符串A和B。两字符串的长度都不超过104,并且保证每个字符串都是由可见的ASCII码和空白字符组成,最后以换行符结束。

输出格式:

在一行中打印出A−B的结果字符串。

输入样例:

I love GPLT!  It's a fun game!
aeiou

输出样例:

I lv GPLT!  It's  fn gm!

代码 

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>

using namespace std;

string str1, str2;

int main() {
    getline(cin, str1);
    getline(cin, str2);
    
    for (int i = 0;i < str2.size();i++) {
          str1.erase(remove(str1.begin(), str1.end(), str2[i]), str1.end());
    }

    cout << str1;

    return 0;
}

 L1-020 帅到没朋友

当芸芸众生忙着在朋友圈中发照片的时候,总有一些人因为太帅而没有朋友。本题就要求你找出那些帅到没有朋友的人。

输入格式:

输入第一行给出一个正整数N(≤100),是已知朋友圈的个数;随后N行,每行首先给出一个正整数K(≤1000),为朋友圈中的人数,然后列出一个朋友圈内的所有人——为方便起见,每人对应一个ID号,为5位数字(从00000到99999),ID间以空格分隔;之后给出一个正整数M(≤10000),为待查询的人数;随后一行中列出M个待查询的ID,以空格分隔。

注意:没有朋友的人可以是根本没安装“朋友圈”,也可以是只有自己一个人在朋友圈的人。虽然有个别自恋狂会自己把自己反复加进朋友圈,但题目保证所有K超过1的朋友圈里都至少有2个不同的人。

输出格式:

按输入的顺序输出那些帅到没朋友的人。ID间用1个空格分隔,行的首尾不得有多余空格。如果没有人太帅,则输出No one is handsome

注意:同一个人可以被查询多次,但只输出一次。

输入样例1:

3
3 11111 22222 55555
2 33333 44444
4 55555 66666 99999 77777
8
55555 44444 10000 88888 22222 11111 23333 88888

输出样例1:

10000 88888 23333

 代码

//大模拟 写的很乱hh
//25.3.15

#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#include <vector>

using namespace std;

int n,cnt = 1;
map<string,int>ma;
map<string,int>maa;
vector<string> arr;

string add(string str){
    string ans = "";
    for(int i = 0;i < 5 - str.size();i ++ ){
        ans += "0";
    }
    ans += str;
    return ans;
}

int main(){
    cin >> n;
    while(n --){
        int m;
        cin >> m;
        if(m == 1){
            string id;
            cin >> id;
            if(id.size() < 5)id = add(id);
            if(ma.count(id) == 0)ma[id] = 0;
        }else{
            for(int i = 0;i < m;i ++){
                string id;
                cin >> id;
                if(id.size() < 5)id = add(id);
                ma[id] = cnt;
            }
            cnt ++;
        }
    }

    int k;
    cin >> k;
    bool sts = false;
    for(int i = 0;i < k; i ++){
        string id;
        cin >> id;
        if(id.size() < 5)id = add(id);
        if((ma.count(id) == 0 || ma[id] == 0) && maa.count(id) == 0){
            arr.push_back(id);
            sts = true;
            maa[id] = 1;
        }
    }
    if(!sts)cout << "No one is handsome";
    else{
        for(int i = 0;i < arr.size();i ++){
            if(i != arr.size() - 1)cout << arr[i] <<' ';
            else cout << arr[i];
        }
    }
    return 0;
}

L1-023 输出GPLT

给定一个长度不超过10000的、仅由英文字母构成的字符串。请将字符重新调整顺序,按GPLTGPLT....这样的顺序输出,并忽略其它字符。当然,四种字符(不区分大小写)的个数不一定是一样多的,若某种字符已经输出完,则余下的字符仍按GPLT的顺序打印,直到所有字符都被输出。

输入格式:

输入在一行中给出一个长度不超过10000的、仅由英文字母构成的非空字符串。

输出格式:

在一行中按题目要求输出排序后的字符串。题目保证输出非空。

输入样例:

pcTclnGloRgLrtLhgljkLhGFauPewSKgt

输出样例:

GPLTGPLTGLTGLGLL

代码 

//字符串简单操作
//25.3.15

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

vector<char>A,B,C,D;

int main(){
    string str;
    cin >> str;

    for(int i = 0;i < str.size();i ++){
        if(str[i] == 'G' || str[i] == 'g')A.push_back('G');
        if(str[i] == 'P' || str[i] == 'p')B.push_back('P');
        if(str[i] == 'L' || str[i] == 'l')C.push_back('L');
        if(str[i] == 'T' || str[i] == 't')D.push_back('T');
        
    }
    
    for(int i = 0;i < A.size() || i < B.size() || i < C.size() || i < D.size();i ++){
        if(i < A.size())cout << A[i];
        if(i < B.size())cout << B[i];
        if(i < C.size())cout << C[i];
        if(i < D.size())cout << D[i];
        
    }
}

L1-027 出租

一时间网上一片求救声,急问这个怎么破。其实这段代码很简单,index数组就是arr数组的下标,index[0]=2 对应 arr[2]=1index[1]=0 对应 arr[0]=8index[2]=3 对应 arr[3]=0,以此类推…… 很容易得到电话号码是18013820100

本题要求你编写一个程序,为任何一个电话号码生成这段代码 —— 事实上,只要生成最前面两行就可以了,后面内容是不变的。

输入格式:

输入在一行中给出一个由11位数字组成的手机号码。

输出格式:

为输入的号码生成代码的前两行,其中arr中的数字必须按递减顺序给出。

输入样例:

18013820100

输出样例:

int[] arr = new int[]{8,3,2,1,0};
int[] index = new int[]{3,0,4,3,1,0,2,4,3,4,4};
//排序去重
//25.3.15

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

vector<int> arr;

int main(){
    string number;
    cin >> number;

    for(int i = 0 ;i < number.size();i ++)arr.push_back(number[i] - '0');

    sort(arr.begin(),arr.end());
    arr.erase(unique(arr.begin(),arr.end()),arr.end());
    reverse(arr.begin(),arr.end());

    cout << "int[] arr = new int[]{";
    for(int i = 0;i < arr.size();i ++){
        if(i != arr.size() - 1)cout << arr[i] <<',';
        else cout << arr[i] << "};" << endl;
    }
    
    cout << "int[] index = new int[]{";
    for(int i = 0;i < number.size();i ++){
        int a = number[i] - '0',idx;

        for(int j = 0;j < arr.size();j ++)
            if(arr[j] == a){idx = j;break;}

        if(i != number.size() - 1)cout << idx << ',';
        else cout << idx << "};";
    }
    return 0;
}

代码

//排序去重
//25.3.15

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

vector<int> arr;

int main(){
    string number;
    cin >> number;

    for(int i = 0 ;i < number.size();i ++)arr.push_back(number[i] - '0');

    sort(arr.begin(),arr.end());
    arr.erase(unique(arr.begin(),arr.end()),arr.end());
    reverse(arr.begin(),arr.end());

    cout << "int[] arr = new int[]{";
    for(int i = 0;i < arr.size();i ++){
        if(i != arr.size() - 1)cout << arr[i] <<',';
        else cout << arr[i] << "};" << endl;
    }
    
    cout << "int[] index = new int[]{";
    for(int i = 0;i < number.size();i ++){
        int a = number[i] - '0',idx;

        for(int j = 0;j < arr.size();j ++)
            if(arr[j] == a){idx = j;break;}

        if(i != number.size() - 1)cout << idx << ',';
        else cout << idx << "};";
    }
    return 0;
}


L1-032 Left-pad

根据新浪微博上的消息,有一位开发者不满NPM(Node Package Manager)的做法,收回了自己的开源代码,其中包括一个叫left-pad的模块,就是这个模块把javascript里面的React/Babel干瘫痪了。这是个什么样的模块?就是在字符串前填充一些东西到一定的长度。例如用*去填充字符串GPLT,使之长度为10,调用left-pad的结果就应该是******GPLT。Node社区曾经对left-pad紧急发布了一个替代,被严重吐槽。下面就请你来实现一下这个模块。

输入格式:

输入在第一行给出一个正整数N(≤104)和一个字符,分别是填充结果字符串的长度和用于填充的字符,中间以1个空格分开。第二行给出原始的非空字符串,以回车结束。

输出格式:

在一行中输出结果字符串。

输入样例1:

15 _
I love GPLT

输出样例1:

____I love GPLT

 代码

//字符串模拟
//25.3.15

#include <iostream>
#include <algorithm>

using namespace std;

int n;
char c;

string pad(string str,int n,char c){
    string res;
    if(n <= str.size())
        for(int i = str.size() - n;i < str.size();i ++)res += str[i];
    else{
        for(int i = 0;i < n - str.size();i ++)res += c;
        res += str;
    }
    return res;
}

int main(){
    cin >> n >> c;
    string s;
    getline(cin,s);
    getline(cin,s);

    string res = pad(s,n,c);

    cout << res;

    return 0;
}

L1-034 点赞

微博上有个“点赞”功能,你可以为你喜欢的博文点个赞表示支持。每篇博文都有一些刻画其特性的标签,而你点赞的博文的类型,也间接刻画了你的特性。本题就要求你写个程序,通过统计一个人点赞的纪录,分析这个人的特性。

输入格式:

输入在第一行给出一个正整数N(≤1000),是该用户点赞的博文数量。随后N行,每行给出一篇被其点赞的博文的特性描述,格式为“K F1​⋯FK​”,其中1≤K≤10,Fi​(i=1,⋯,K)是特性标签的编号,我们将所有特性标签从1到1000编号。数字间以空格分隔。

输出格式:

统计所有被点赞的博文中最常出现的那个特性标签,在一行中输出它的编号和出现次数,数字间隔1个空格。如果有并列,则输出编号最大的那个。

输入样例:

4
3 889 233 2
5 100 3 233 2 73
4 3 73 889 2
2 233 123

输出样例:

233 3

 代码

//模拟
//25.3.15

#include <iostream>
#include <algorithm>
#include <map>

using namespace std;

map<int,int>ma;

int main(){
    int n;
    cin >> n;

    while(n --){
        int m;
        cin >> m;
        for(int i = 0;i < m;i ++){
            int x;
            cin >> x;
            if(!ma.count(x))ma[x] = 1;
            else ma[x] ++;
        }
    }

    int num = 0,max = 0;
    for(auto t : ma){
        if(t.second >= max){
            num = t.first;
            max = t.second;
        }
    }

    cout << num <<' '<<max;

    return 0;
}

L1-039 古风排版

中国的古人写文字,是从右向左竖向排版的。本题就请你编写程序,把一段文字按古风排版。

输入格式:

输入在第一行给出一个正整数N(<100),是每一列的字符数。第二行给出一个长度不超过1000的非空字符串,以回车结束。

输出格式:

按古风格式排版给定的字符串,每列N个字符(除了最后一列可能不足N个)。

输入样例:

4
This is a test case

输出样例:

asa T
st ih
e tsi
 ce s

代码 

//数组存储
//25.3.15
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 110;
char g[N][N];
int n;
string str;

int main(){
    cin >> n;
    getline(cin,str);
    getline(cin,str);

    int row = n,col;
    memset(g,' ',sizeof g);
    if(str.size() % n == 0)col = str.size() / n;
    else col = str.size() / n + 1;

    int cnt = 0;
    for(int i = col - 1;i >= 0;i --)
        for(int j = 0;j < row;j ++){
            if(cnt < str.size())g[j][i] = str[cnt];
            else g[j][i] = ' ';
            
            cnt ++;
        }
    
    for(int i = 0;i < row;i ++){
        for(int j = 0;j < col;j ++){
            cout << g[i][j];
        }
        cout << endl;
    }

    return 0;
}

L1-043 阅览室

天梯图书阅览室请你编写一个简单的图书借阅统计程序。当读者借书时,管理员输入书号并按下S键,程序开始计时;当读者还书时,管理员输入书号并按下E键,程序结束计时。书号为不超过1000的正整数。当管理员将0作为书号输入时,表示一天工作结束,你的程序应输出当天的读者借书次数和平均阅读时间。

注意:由于线路偶尔会有故障,可能出现不完整的纪录,即只有S没有E,或者只有E没有S的纪录,系统应能自动忽略这种无效纪录。另外,题目保证书号是书的唯一标识,同一本书在任何时间区间内只可能被一位读者借阅。

输入格式:

输入在第一行给出一个正整数N(≤10),随后给出N天的纪录。每天的纪录由若干次借阅操作组成,每次操作占一行,格式为:

书号([1, 1000]内的整数) 键值SE发生时间hh:mm,其中hh是[0,23]内的整数,mm是[0, 59]内整数)

每一天的纪录保证按时间递增的顺序给出。

输出格式:

对每天的纪录,在一行中输出当天的读者借书次数和平均阅读时间(以分钟为单位的精确到个位的整数时间)。

输入样例:

3
1 S 08:10
2 S 08:35
1 E 10:00
2 E 13:16
0 S 17:00
0 S 17:00
3 E 08:10
1 S 08:20
2 S 09:00
1 E 09:20
0 E 17:00

输出样例:

2 196
0 0
1 60

 代码

//不想模拟了啊啊啊啊啊啊啊啊啊啊aaaaaaaaa
//25.3.15
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1010;

struct node{
    bool st;
    int begin,end;
}BookNum[N];

int n;

int main(){
    cin >> n;
    while(n --){
        int x;
        int cnt = 0,minite = 0;
        
        while(cin >> x){
            
            char c;
            int hh,mm;
            cin >> c;
            scanf("%02d:%02d",&hh,&mm);
            if(!x)break;
            if(c == 'E' && BookNum[x].st == false)continue;
            if(c == 'S'){
                BookNum[x].st = true;
                BookNum[x].begin = hh * 60 + mm;
            }else{
                cnt ++;
                BookNum[x].end = hh * 60 + mm;
                minite += (BookNum[x].end - BookNum[x].begin);
                BookNum[x].st = false;
                BookNum[x].begin = 0;
                BookNum[x].end = 0;
            }
        }
        if(cnt)printf("%d %.0lf\n",cnt,(double)minite / cnt);
        else cout << cnt << ' ' << minite << endl;
    }

    return 0;
}

L1-046 整除光棍

这里所谓的“光棍”,并不是指单身汪啦~ 说的是全部由1组成的数字,比如1、11、111、1111等。传说任何一个光棍都能被一个不以5结尾的奇数整除。比如,111111就可以被13整除。 现在,你的程序要读入一个整数x,这个整数一定是奇数并且不以5结尾。然后,经过计算,输出两个数字:第一个数字s,表示x乘以s是一个光棍,第二个数字n是这个光棍的位数。这样的解当然不是唯一的,题目要求你输出最小的解。

提示:一个显然的办法是逐渐增加光棍的位数,直到可以整除x为止。但难点在于,s可能是个非常大的数 —— 比如,程序输入31,那么就输出3584229390681和15,因为31乘以3584229390681的结果是111111111111111,一共15个1。

输入格式:

输入在一行中给出一个不以5结尾的正奇数x(<1000)。

输出格式:

在一行中输出相应的最小的sn,其间以1个空格分隔。

输入样例:

31

输出样例:

3584229390681 15

代码 

//高精度除法啦
//25.3.15 23:01
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

vector<int> div(vector<int>A,int b,int &r){
    r = 0;
    vector<int>C;

    for(int i = A.size() - 1;i >= 0;i --){
        r =r * 10 + A[i];
        C.push_back(r / b);
        r %= b;
    }
    
    reverse(C.begin(),C.end());
    while(C.size() > 1 && C.back() == 0)C.pop_back();

    return C;
}

int main(){
    int x;
    cin >> x;
    vector<int>A;

    for(int i = 0;i <= 10000;i ++){
        A.push_back(1);

        int r;
        vector<int>C = div(A,x,r);
        if(!r){
            for(int i = C.size() - 1;i >= 0;i --)cout << C[i];
            cout << ' ' << A.size();
            break;
        }
    }
    return 0;
}

L1-049 天梯赛座位分配

天梯赛每年有大量参赛队员,要保证同一所学校的所有队员都不能相邻,分配座位就成为一件比较麻烦的事情。为此我们制定如下策略:假设某赛场有 N 所学校参赛,第 i 所学校有 M[i] 支队伍,每队 10 位参赛选手。令每校选手排成一列纵队,第 i+1 队的选手排在第 i 队选手之后。从第 1 所学校开始,各校的第 1 位队员顺次入座,然后是各校的第 2 位队员…… 以此类推。如果最后只剩下 1 所学校的队伍还没有分配座位,则需要安排他们的队员隔位就坐。本题就要求你编写程序,自动为各校生成队员的座位号,从 1 开始编号。

输入格式:

输入在一行中给出参赛的高校数 N (不超过100的正整数);第二行给出 N 个不超过10的正整数,其中第 i 个数对应第 i 所高校的参赛队伍数,数字间以空格分隔。

输出格式:

从第 1 所高校的第 1 支队伍开始,顺次输出队员的座位号。每队占一行,座位号间以 1 个空格分隔,行首尾不得有多余空格。另外,每所高校的第一行按“#X”输出该校的编号X,从 1 开始。

输入样例:

3
3 4 2

输出样例:

#1
1 4 7 10 13 16 19 22 25 28
31 34 37 40 43 46 49 52 55 58
61 63 65 67 69 71 73 75 77 79
#2
2 5 8 11 14 17 20 23 26 29
32 35 38 41 44 47 50 53 56 59
62 64 66 68 70 72 74 76 78 80
82 84 86 88 90 92 94 96 98 100
#3
3 6 9 12 15 18 21 24 27 30
33 36 39 42 45 48 51 54 57 60

 代码

//模拟 ps:调了半个小时才对hh
//25.3.16

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

const int N = 1010;

int a[N];
vector<int>g[N];
bool st[N];
int n;

int main(){
    cin >> n;
    int s;
    for(int i = 1;i <= n;i ++){
        cin >> a[i];
        a[i] *= 10;
    }
    int cnt = 1,num = n;
    for(int i = 1;i <= n;i ++){
        if(g[i].size() < a[i]){
            if(num == 1){
                for(int j = g[i].size();j < a[i];j ++){
                    
                    g[i].push_back(cnt);
                    cnt += 2;
                }
                break;
            }else{
                g[i].push_back(cnt);
                cnt ++;
                if(g[i].size() == a[i]){
                    num --;
                    st[i] = true;
                }
            }
        }else if(!st[i]){
            num --;
            st[i] = true;
        }
        
        if(i == n)i = 0;
    }
    
    for(int i = 1;i <= n;i ++){
        cout << "#" << i;
        for(int j = 0;j < g[i].size();j ++){
            if(j % 10 == 0)cout << endl;
            if((j + 1) % 10 == 0)cout << g[i][j];
            else cout << g[i][j] <<' ';
        }
        cout << endl;
    }
    
}

L1-056 猜数字

一群人坐在一起,每人猜一个 100 以内的数,谁的数字最接近大家平均数的一半就赢。本题就要求你找出其中的赢家。

输入格式:

输入在第一行给出一个正整数N(≤104)。随后 N 行,每行给出一个玩家的名字(由不超过8个英文字母组成的字符串)和其猜的正整数(≤ 100)。

输出格式:

在一行中顺序输出:大家平均数的一半(只输出整数部分)、赢家的名字,其间以空格分隔。题目保证赢家是唯一的。

输入样例:

7
Bob 35
Amy 28
James 98
Alice 11
Jack 45
Smith 33
Chris 62

输出样例:

22 Amy

代码 

//25.3.16
//二分即可,但是数据范围太小了,似乎暴力就能过...
//map 可以自动从小到大排序 虽然这题没用

#include <iostream>
#include <algorithm>
#include <map>

using namespace std;

const int N = 10010;

map<int,string>ma;
int n,sum = 0,veg;
int a[N];

int main(){
    cin >> n;
    for(int i = 0;i < n;i ++){
        string name;
        int x;
        cin >> name >> x;
        ma[x] = name;
        sum += x;
        a[i] = x;
    }
    
    sort(a,a + n);
    veg = sum / n / 2;
    
    int l = 0,r = n - 1;
    while(l < r){
        int mid = l + r >> 1;
        if(a[mid] >= veg)r = mid;
        else l = mid + 1;
    }
    
    int res;
    if(abs(a[l] - veg) < abs(a[r] - veg))res = a[l];
    else res = a[r];
    
    cout << veg << ' ' << ma[res];
    
    return 0;
}

L1-059 敲笨钟

微博上有个自称“大笨钟V”的家伙,每天敲钟催促码农们爱惜身体早点睡觉。为了增加敲钟的趣味性,还会糟改几句古诗词。其糟改的方法为:去网上搜寻压“ong”韵的古诗词,把句尾的三个字换成“敲笨钟”。例如唐代诗人李贺有名句曰:“寻章摘句老雕虫,晓月当帘挂玉弓”,其中“虫”(chong)和“弓”(gong)都压了“ong”韵。于是这句诗就被糟改为“寻章摘句老雕虫,晓月当帘敲笨钟”。

现在给你一大堆古诗词句,要求你写个程序自动将压“ong”韵的句子糟改成“敲笨钟”。

输入格式:

输入首先在第一行给出一个不超过 20 的正整数 N。随后 N 行,每行用汉语拼音给出一句古诗词,分上下两半句,用逗号 , 分隔,句号 . 结尾。相邻两字的拼音之间用一个空格分隔。题目保证每个字的拼音不超过 6 个字符,每行字符的总长度不超过 100,并且下半句诗至少有 3 个字。

输出格式:

对每一行诗句,判断其是否压“ong”韵。即上下两句末尾的字都是“ong”结尾。如果是压此韵的,就按题面方法糟改之后输出,输出格式同输入;否则输出 Skipped,即跳过此句。

输入样例:

5
xun zhang zhai ju lao diao chong, xiao yue dang lian gua yu gong.
tian sheng wo cai bi you yong, qian jin san jin huan fu lai.
xue zhui rou zhi leng wei rong, an xiao chen jing shu wei long.
zuo ye xing chen zuo ye feng, hua lou xi pan gui tang dong.
ren xian gui hua luo, ye jing chun shan kong.

输出样例:

xun zhang zhai ju lao diao chong, xiao yue dang lian qiao ben zhong.
Skipped
xue zhui rou zhi leng wei rong, an xiao chen jing qiao ben zhong.
Skipped
Skipped

代码 

//字符串处理 sstream流操作
//搞半天发现ben写成beng了
//25.3.16

#include <iostream>
#include <algorithm>
#include <sstream>
#include <cstring>
#include <vector>

using namespace std;

int n;
string lang[3] = {"qiao","ben","zhong."};

bool check(string data){
    int siz = data.size();
    return data[siz - 4] == 'o' && data[siz - 3] == 'n' && data[siz - 2] == 'g';
}

int main(){
    cin >> n;
    //整掉可恶的回车
    string str;
    getline(cin,str);
    while(n -- ){
        vector<string> alls;
        string str;
        getline(cin,str);
        
        stringstream ssin(str);
        string data;
        int cnt = 0;
        while(ssin >> data){
            alls.push_back(data);
            if((data[data.size() - 1] == ',' || data[data.size() - 1] == '.') && data.size() >= 3){
                if(check(data))cnt ++;
            }
        }
        if(cnt != 2)cout << "Skipped" << endl;
        else{
            for(int i = 0;i < alls.size() - 3;i ++)cout << alls[i] <<' ';
            for(int i = 0;i < 3;i ++){
                if(i != 2)cout << lang[i] << ' ';
                else cout << lang[i];
            }
            cout << endl;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值