寒假pta

打印沙漏

本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打

*****
 ***
  *
 ***
*****

所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。

给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。

输入格式:
输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。
输出格式:
首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。
输入样例:

19 *

输出样例:

*****
 ***
  *
 ***
*****
2

简单的模拟,简单的输出,

#include <bits/stdc++.h>
using namespace std;
int n,t,row,sum;
char c;
int  main() {
    //freopen("in","r",stdin);
    cin >> n >> c;
    for(int i = 1; ; i++){
       if((2 * i * i - 1) > n) break;
        else {
            t = 2 * i * i - 1;
            row = i;
        }
    }
    sum = t;
    int s = 2 * row - 1;
    for(int i = 1; i <= row; i++){
        if(i > 1){
            for(int k = 1; k < i; k++)
                cout << " ";
        }
        for(int j = s; j >= 1; j--){

            cout << c;

        }
        s = s - 2;
        cout << endl;
    }

    s = 3;
    int tt = 2 * row - 1;
    for(int i =  2; i <= row; i++){
            for(int k = 1; k <= ((tt - s) / 2); k++)
                cout << " ";

        for(int j = s; j >= 1; j--){
            cout << c;
        }
        cout << endl;
        s += 2;
        //if(s == (2 * row - 1)) break;

    }
    cout << n - t << endl;

}

连续因子

一个正整数 N 的因子中可能存在若干连续的数字。例如 630 可以分解为 3×5×6×7,其中 5、6、7 就是 3 个连续的数字。给定任一正整数 N,要求编写程序求出最长连续因子的个数,并输出最小的连续因子序列。
输入格式:
输入在一行中给出一个正整数 N(1<N<2 ^ ​31)。
输出格式:
首先在第 1 行输出最长连续因子的个数;然后在第 2 行中按 因子1因子2……*因子k 的格式输出最小的连续因子序列,其中因子按递增顺序输出,1 不算在内。
输入样例:
630
输出样例:
3
5 * 6 * 7(中间没有的空格)

#include <bits/stdc++.h>
using namespace std;
#define int long long
int n;
int bg;
int len;
int prd = 1;
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for(int i = 2; i <= sqrt(n); i++){
        prd = 1;
        for(int j = i; prd * j <= n; j++){
            prd *= j;
            if(!(n % prd) && (j - i + 1 > len)){
               bg = i;
               len = j - i + 1;
            }
        }
    }
    if(!bg){
        bg = n;
        len = 1;
    }
    cout << len << endl;
    cout << bg;
    for(int i = bg + 1; i < bg + len;i++)
        cout << "*" << i;
    return 0;
}

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
输入样例2:
2
4/3 2/3
输出样例2:
2
输入样例3:
3
1/3 -1/6 1/8
输出样例3:
7/24

#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,x,y,xx,yy;
int yinzi,minbs;
signed main(){
    cin >> n;
    scanf("%lld/%lld",&x,&y);
    n--;
    while(n){
        scanf("%lld/%lld",&xx,&yy);
        //通分
        minbs = y * (yy / (__gcd(y,yy)));
        x = x * (minbs / y) + xx *( minbs / yy);
        y = minbs;
        //约分
        yinzi = __gcd(x,y);
        x /= yinzi;
        y /= yinzi;
        n--;
    }
    n = x / y;
    x = x - n * y;
    if(!n && x) cout << x << "/" << y << endl;
    else {
        if(!x) cout << n << endl;
        else cout << n << " " << x << "/" << y << endl;
    }
    return 0;
}

在这里插入图片描述
刚开始的时候最后一个样例没有过,所以又在if里面加了&x

QAQ,我太难了
在这里插入图片描述

查验身份证

一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下:
首先对前17位数字加权求和,权重分配为:{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};然后将计算的和对11取模得到值Z;最后按照以下关系对应Z值与校验码M的值:

Z:0 1 2 3 4 5 6 7 8 9 10
M:1 0 X 9 8 7 6 5 4 3 2

现在给定一些身份证号码,请你验证校验码的有效性,并输出有问题的号码。

输入格式:
输入第一行给出正整数N(≤100)是输入的身份证号码的个数。随后N行,每行给出1个18位身份证号码。

输出格式:
按照输入的顺序每行输出1个有问题的身份证号码。这里并不检验前17位是否合理,只检查前17位是否全为数字且最后1位校验码计算准确。如果所有号码都正常,则输出All passed。

输入样例1:

4
320124198808240056
12010X198901011234
110108196711301866
37070419881216001X

输出样例1:
12010X198901011234
110108196711301866
37070419881216001X

输入样例2:

2
320124198808240056
110108196711301862

输出样例2:
All passed

#include <bits/stdc++.h>
using namespace std;

int n,a[19] = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
char c[19] = {'1','0','X','9','8','7','6','5','4','3','2'};
int sum,flag;
string s;
int cnt;
int main(){
    //freopen("in","r",stdin);
    cin >> n;
    while(n--){
        flag = 1;
        cin >> s;
        sum = 0;
        //cout<< s << endl;
        for(int i = 0; i < 17; i++){
            //有字母
            if((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z')){
                flag = 0;
                break;
            }
            //没有字母
            sum = sum + (a[i] * (s[i] - '0'));
            sum %= 11;

        }

        //cout << c[sum] << " " << s[17] << endl;
        if (c[sum] != s[17])
            flag = 0;

        if(!flag){
            cnt++;
            cout << s << endl;
        }
    }
    if(!cnt) cout << "All passed" << endl;

    return 0;
}

这又是一次我做的很愚蠢的题了,我尽然没有sum =0 ,

在这里插入图片描述

帅到没朋友

当芸芸众生忙着在朋友圈中发照片的时候,总有一些人因为太帅而没有朋友。本题就要求你找出那些帅到没有朋友的人。
输入格式:
输入第一行给出一个正整数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
输入样例2:

3
3 11111 22222 55555
2 33333 44444
4 55555 66666 99999 77777
4
55555 44444 22222 11111

输出样例2:
No one is handsome

#include <bits/stdc++.h>
using namespace std;

int n,k,it,m,cnt = 0;
int a[100000],c[100000];
int main(){
   // freopen("in","r",stdin);
    cin >> n ;
    while(n--){
        cin >> k;
        if(k==1) {
            cin >> it;
            continue;
        }
        while(k--){
            cin >> it;
            a[it]++;
        }

    }
    cin >> m;
    //cout << m << endl;
    while(m--){
        cin >> it;
        if(!a[it] && !c[it]) {
            c[it] = 1;
            cnt++;
            if(cnt == 1) printf("%05d",it);
            else printf(" %05d",it);
        }
    }
    if(!cnt) puts("No one is handsome");
    return 0;
}

不要想得太复杂了,结构体都出来了。。
注意输出格式

正整数A+B

题的目标很简单,就是求两个正整数A和B的和,其中A和B都在区间[1,1000]。稍微有点麻烦的是,输入并不保证是两个正整数。
输入格式:
输入在一行给出A和B,其间以空格分开。问题是A和B不一定是满足要求的正整数,有时候可能是超出范围的数字、负数、带小数点的实数、甚至是一堆乱码。
注意:我们把输入中出现的第1个空格认为是A和B的分隔。题目保证至少存在一个空格,并且B不是一个空字符串。
输出格式:
如果输入的确是两个正整数,则按格式A + B = 和输出。如果某个输入不合要求,则在相应位置输出?,显然此时和也是?。
输入样例1:

123 456    

输出样例1:
123 + 456 = 579
输入样例2:

22. 18 

输出样例2:
? + 18 = ?
输入样例3:

-100 blabla bla...33

输出样例3:
? + ? = ?

#include <bits/stdc++.h>
using namespace std;
string s;
int sa,sb,fa = 1,fb = 1;
int main(){
    //freopen("in","r",stdin);
    getline(cin,s);
    //cout << s;
    for(int i = 0; i < s.size(); i++){
        if(s[i] == ' '){
            for(int j = 0; j < i; j++){
                if(s[j] < '0' || s[j] > '9'){
                    fa = 0;break;
                }
                else
                    sa = sa * 10 + (s[j] - '0');
            }
            if(s[0] == ' ')//忘记了
                fa = 0;
            if(sa <= 0 || sa > 1000) fa = 0;
            for(int j = i + 1; j < s.size(); j++){

                if(s[j] < '0' || s[j] > '9'){
                    fb = 0;break;
                }
                else
                    sb = sb * 10 + (s[j] - '0');
            }
            if(sb <= 0 || sb > 1000) fb = 0;
            break;//当时我忘记写了
        }
    }
    if(fa){
        if(fb) cout << sa << " + " << sb << " = " << sa + sb << endl;
        else cout << sa << " + ?" << " = ?" << endl;
    }
    else {
        if (fb) cout << "? + " << sb << " = ?" << endl;
        else cout << "? + ?" << " = ?" << endl;
    }
    return 0;
}

这道题是目前卡我卡的最久的一道了
QAQ哎~~

喊山

喊山,是人双手围在嘴边成喇叭状,对着远方高山发出“喂—喂喂—喂喂喂……”的呼唤。呼唤声通过空气的传递,回荡于深谷之间,传送到人们耳中,发出约定俗成的“讯号”,达到声讯传递交流的目的。原来它是彝族先民用来求援呼救的“讯号”,慢慢地人们在生活实践中发现了它的实用价值,便把它作为一种交流工具世代传袭使用。(图文摘自:http://news.xrxxw.com/newsshow-8018.html)
一个山头呼喊的声音可以被临近的山头同时听到。题目假设每个山头最多有两个能听到它的临近山头。给定任意一个发出原始信号的山头,本题请你找出这个信号最远能传达到的地方。
输入格式:
输入第一行给出3个正整数n、m和k,其中n(≤10000)是总的山头数(于是假设每个山头从1到n编号)。接下来的m行,每行给出2个不超过n的正整数,数字间用空格分开,分别代表可以听到彼此的两个山头的编号。这里保证每一对山头只被输入一次,不会有重复的关系输入。最后一行给出k(≤10)个不超过n的正整数,数字间用空格分开,代表需要查询的山头的编号。
输出格式:
依次对于输入中的每个被查询的山头,在一行中输出其发出的呼喊能够连锁传达到的最远的那个山头。注意:被输出的首先必须是被查询的个山头能连锁传到的。若这样的山头不只一个,则输出编号最小的那个。若此山头的呼喊无法传到任何其他山头,则输出0。
输入样例:

7 5 4
1 2
2 3
3 1
4 5
5 6
1 4 5 7

输出样例:
2
6
4
0

#include <bits/stdc++.h>
using namespace std;
int n,m,k;
int u,v,it;
vector<int> ve[10010];
queue<int>que;
int vis[10010];
int step[10010];
int bfs(int u){
    memset(vis,0, sizeof(vis));
    memset(step,0, sizeof(step));
    que.push(u);
    vis[u] = 1;
    while(!que.empty()) {
        int tp = que.front();
        que.pop();
        for (int i = 0; i < ve[tp].size(); i++) {
            if(!vis[ve[tp][i]]){
                step[ve[tp][i]] = step[tp] + 1;
                vis[ve[tp][i]] = 1;
                que.push(ve[tp][i]);
            }
        }
    }
    int dis = 0,ans = 0;
    for(int i = 1; i <= n; i++){
        if(step[i] > dis){
            ans = i;
            dis = step[i];
        }
    }
    return ans;
}
int main(){
    cin >> n >> m >> k;
    while(m--){
        cin >> u >> v;
        ve[u].push_back(v);
        ve[v].push_back(u);
    }
    while(k--){
        cin >> it;
        cout << bfs(it) << endl;
    }
    return 0;
}

出租

下面是新浪微博上曾经很火的一张图:

在这里插入图片描述

一时间网上一片求救声,急问这个怎么破。其实这段代码很简单,index数组就是arr数组的下标,index[0]=2 对应 arr[2]=1,index[1]=0 对应 arr[0]=8,index[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};

#include <bits/stdc++.h>
using namespace std;
string s;
int flag,cnt;
int tel[20],ar[20],inde[20];
bool cmp(int a,int b){
    return a > b;
}
int main(){
   // freopen("in","r",stdin);
    cin >> s;
    for(int i = 0;i < s.size();i++){
        flag = 1;
        tel[i] = s[i] - '0';
        for(int j = 0; j < i;j++){
            if(s[j] == s[i]){
                flag = 0;
                break;
            }
        }
        if(flag){
            ar[cnt++] = tel[i];
        }
    }
    sort(ar,ar + cnt,cmp);
    cout << "int[] arr = new int[]{";
    for(int i = 0; i < cnt; i++){
        if(!i) cout << ar[0];
        else cout << "," << ar[i];
    }
    cout << "};" << endl;

    //arr[index[i]] = s[i] - '0';
    for(int i = 0; i < s.size(); i++){
        for(int j = 0; j < cnt; j++){
            if(s[i] - '0' == ar[j]){
                inde[i] = j;
                break;
            }
        }
    }
    cout << "int[] index = new int[]{";
    for(int i = 0;i < s.size();i++){
        if(!i) cout << inde[0];
        else cout << "," <<inde[i];
    }
    cout << "};" << endl;
    return 0;
}

代码中用arr,index,pta上编译错误,…

出生年

出生年

点赞

微博上有个“点赞”功能,你可以为你喜欢的博文点个赞表示支持。每篇博文都有一些刻画其特性的标签,而你点赞的博文的类型,也间接刻画了你的特性。本题就要求你写个程序,通过统计一个人点赞的纪录,分析这个人的特性。
输入格式:
输入在第一行给出一个正整数N(≤1000),是该用户点赞的博文数量。随后N行,每行给出一篇被其点赞的博文的特性描述,格式为“K F1​​ ⋯F​K ”,其中1≤K≤10,F​i(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

#include <bits/stdc++.h>
using namespace std;
int n,k,it;
struct node{
    int num;
    int cnt;
}a[1010];
int cmp(node a,node b){
    if(a.cnt != b.cnt)
        return a.cnt > b.cnt;
    return a.num > b.num;
}
int main(){
    //freopen("in","r",stdin);
    cin >> n;
    while(n--){
       cin >> k;
       while(k--){

           //......
           cin >> it;
           a[it].cnt++;
           a[it].num = it;
       }
    }
    sort(a,a+1010,cmp);
    cout << a[0].num << " " << a[0].cnt;
    return 0;
}

QAQ23333… … … … …

阅览室

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

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

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

书号([1, 1000]内的整数) 键值(S或E) 发生时间(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

#include <bits/stdc++.h>
using namespace std;
int t,n,h,m;
char c;
int sum,ct;
int flag[1005],s[1005];
int main(){
    //freopen("in","r",stdin);
    cin >> t;
    while(t--) {
        memset(flag, 0, sizeof(flag));
        ct = sum = 0;
        memset(s, 0, sizeof(s));
        while (scanf("%d %c %d:%d", &n, &c, &h, &m) != EOF && n) {
            if (c == 'S') {
                flag[n] = 1;//已借书
                s[n] = h * 60 + m;
            } else {
                if (flag[n]) {
                    sum += (h * 60 + m - s[n]);
                    flag[n] = 0;
                    ct++;
                }
            }
        }
        if (!ct) puts("0 0");
        else printf("%d %.0lf\n", ct, (double) sum / ct);
    }
    return 0;
}

参考的以为大佬的代码,实现简单

6翻了

666.JPG

“666”是一种网络用语,大概是表示某人很厉害、我们很佩服的意思。最近又衍生出另一个数字“9”,意思是“6翻了”,实在太厉害的意思。如果你以为这就是厉害的最高境界,那就错啦 —— 目前的最高境界是数字“27”,因为这是 3 个 “9”!

本题就请你编写程序,将那些过时的、只会用一连串“6666……6”表达仰慕的句子,翻译成最新的高级表达。

输入格式:
输入在一行中给出一句话,即一个非空字符串,由不超过 1000 个英文字母、数字和空格组成,以回车结束。

输出格式:
从左到右扫描输入的句子:如果句子中有超过 3 个连续的 6,则将这串连续的 6 替换成 9;但如果有超过 9 个连续的 6,则将这串连续的 6 替换成 27。其他内容不受影响,原样输出。

输入样例:

it is so 666 really 6666 what else can I say 6666666666

输出样例:
it is so 666 really 9 what else can I say 27

#include <bits/stdc++.h>
using namespace std;
string s;
int ct;
int main(){
    //freopen("in","r",stdin);
    getline(cin,s);
    for(int i = 0; i < s.size();i++){
        if(s[i]=='6'){
            ct++;
        }else{
            if(ct > 9){
                cout << "27";
            }else if(ct > 3){
                cout << "9";
            }else{
                while(ct--)
                    cout << "6";
            }
            ct = 0;
            cout << s[i];
        }
    }
    if(ct > 9){
        cout << "27";
    }else if(ct > 3){
        cout << "9";
    }else{
        while(ct--)
            cout << "6";
    }
    return 0;
}

敲笨钟

微博上有个自称“大笨钟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

#include <bits/stdc++.h>
using namespace std;
string a,b,s;
int n,i,cnt;
int l1,l2;
int main(){
    //freopen("in","r",stdin);
    scanf("%d\n",&n);
    while(n--){
        getline(cin,a,',');
        getline(cin,b,'.');
        getchar();
        l1 = a.size();
        l2 = b.size();

        if(l1 >= 3 && a.substr(l1 - 3) == "ong" && b.substr(l2 - 3) == "ong"){
            cnt = 0;
            for(i = l2 - 1; i >= 0;i--){
                if(b.at(i) == ' '){
                    cnt++;
                    if(cnt == 3){
                        break;
                    }
                }
            }
           b.erase(i);
            cout << a << ',' << b << " qiao ben zhong." << endl;
        }else cout << "Skipped\n";

    }
    return 0;
}
发布了90 篇原创文章 · 获赞 4 · 访问量 9497

猜你喜欢

转载自blog.csdn.net/xcfkaixin/article/details/103944437
PTA