天梯赛 L1_001-L1_020 集合

文章目录

天梯赛

L1-001 Hello World (5分)

这道超级简单的题目没有任何输入。

你只需要在一行中输出著名短句“Hello World!”就可以了。

输入样例:

输出样例:

Hello World!    

答案:

#include <iostream>

using namespace std;

int main()
{
    cout << "Hello World!" << endl;
    return 0;
}

L1-002 打印沙漏 (20分)

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

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

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

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

输入格式:

输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。

输出格式:

首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。

输入样例:

19 *    

输出样例:

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

答案:

注意每一行字符后不可以加空格,否则无法通过测试,会出现格式错误

#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    int n;
    char c;
    scanf("%d %c",&n, &c);
    int m = (n + 1)/2;
    int i = 0;
    while(i*i <= m)
        i++;
    int k = --i;
    for(int j = 0; j < k; j++){              //打印上半部分
        for(int q = 0; q < j; q++){
            printf(" ");
        }
        for(int p = 0; p < 2*i-1; p++){
            printf("%c",c);
        }
        /*for(int q = 0; q < j; q++){
            printf(" ");
        }
        */                                     //字符后不可以有空格
        printf("\n");
        i--;
    }
    i++;
    i++;                                       //i+=2; 
    for(int j = k -1; j > 0; j--){              //打印下半部分
        for(int q = j-1; q > 0; q--){
            printf(" ");
        }
        for(int p = 0; p < 2*i-1; p++){
            printf("%c",c);
        }
        /*for(int q = j-1; q > 0; q--){
            printf(" ");
        }
        */                                   //字符后不可以有空格
        printf("\n");
        i++;
    }
    i = (i-1)*(i-1)*2 - 1;
    m = n - i;
    printf("%d", m);                     //printf("%d", n - i);
}

L1-003 个位数统计 (15分)

给定一个 k 位整数 N = d k 1 1 0 k 1 + + d 1 1 0 1 + d 0 ( 0 d i 9 , i = 0 , , k 1 , d k 1 > 0 ) N=d_{k−1}10^{k−1}+⋯+d_110^1+d_0 \quad(0≤d_i≤9, i=0,⋯,k−1, d_{k−1}>0) ,请编写程序统计每种不同的个位数字出现的次数。例如:给定 N = 100311 N=100311 ,则有 2 个 0,3 个 1,和 1 个 3。

扫描二维码关注公众号,回复: 9429149 查看本文章

输入格式:

每个输入包含 1 个测试用例,即一个不超过 1000 位的正整数 N

输出格式:

N 中每一种不同的个位数字,以 D:M 的格式在一行中输出该位数字 D 及其在 N 中出现的次数 M。要求按 D 的升序输出。

输入样例:

100311

输出样例:

0:2
1:3
3:1

答案1

此答案无法通过第三个测试点,因未注意到N的位数,正整数位数过多时无法用int 或 long int 表示

#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    int N = 0;
    int i = 0;
    scanf("%d", &N);
    int a[10] = {0};
    //printf("1\n");

    while(N / 10 != 0){
        i = N % 10;
        a[i]++;
        N = N / 10;
        //printf("2\n");
    }
    a[N]++;
    for(int j = 0; j <= 9; j++){
        if(a[j] != 0){
            printf("%d:%d\n",j, a[j]);
        }
    }
    return 0;
}

答案2

#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;
int maxn = 1010;

int main(){
    char str[maxn];
    int a[10];
    int i, len;
    while(cin>>str){        //while(scanf("%s",str)!=EOF)
        len = strlen(str);
        memset(a, 0, sizeof(a));
        for(i = 0; i < len; i++){
            a[str[i] - '0']++;
        }
        for(i = 0; i < 10; i++){
            if(a[i] != 0){
                printf("%d:%d\n", i, a[i]);
            }
        }
    }
    return 0;
}

cin>>str代表获取键盘输入的值赋值给变量str,将cin>>str置于while的循环条件内即while(cin>>str),将会一直测试输入流是否正常。

如果输入流正常,就会继续循环获取键盘值,如果输入流错误,或者达到文件末尾(在windows下Ctrl+Z,在Linux下Ctrl+D),该循环就会终止。

等同于C中的 while(scanf("%s",str)!=EOF)

L1-004 计算摄氏温度 (5分)

给定一个华氏温度 F F ,本题要求编写程序,计算对应的摄氏温度 C C 。计算公式: C = 5 × ( F 32 ) / 9 C=5×(F−32)/9 。题目保证输入与输出均在整型范围内。

输入格式:

输入在一行中给出一个华氏温度。

输出格式:

在一行中按照格式“Celsius = C”输出对应的摄氏温度C的整数值。

输入样例:

150 

输出样例:

Celsius = 65

答案

#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    int f, c;
    scanf("%d", &f);
    c = 5 * (f - 32)/9;
    printf("Celsius = %d", c);
    return 0;
}

L1-005 考试座位号 (15分)

每个 PAT 考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位。正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试座位号码,考试时考生需要换到考试座位就座。但有些考生迟到了,试机已经结束,他们只能拿着领到的试机座位号码求助于你,从后台查出他们的考试座位号码。

输入格式:

输入第一行给出一个正整数 N(≤1000),随后 N 行,每行给出一个考生的信息:准考证号 试机座位号 考试座位号。其中准考证号由 16 位数字组成,座位从 1 到 N 编号。输入保证每个人的准考证号都不同,并且任何时候都不会把两个人分配到同一个座位上。

考生信息之后,给出一个正整数 M(≤N),随后一行中给出 M 个待查询的试机座位号码,以空格分隔。

输出格式:

对应每个需要查询的试机座位号码,在一行中输出对应考生的准考证号和考试座位号码,中间用 1 个空格分隔。

输入样例:

4
3310120150912233 2 4
3310120150912119 4 1
3310120150912126 1 3
3310120150912002 3 2
2
3 4 

输出样例:

3310120150912002 2
3310120150912119 1

答案1

数组方式

#include <iostream>
#include <stdio.h>

using namespace std;

const int MAX = 1010;
char s[MAX+1][16];
int a[MAX+1];
int b[MAX+1];

int main()
{
    int N, x, y;
    scanf("%d", &N);
    for(int i = 0; i < N; i++){
        scanf("%s %d %d", &s[i], &a[i], &b[i]);  
    }
    scanf("%d", &x);
    for(int j = 0; j < x; j++){
        scanf("%d", &y);
        for(int k = 0; k < N; k++){
            if(y == a[k]){
                for(int t = 0; t < 16; t++){
                    printf("%c", s[k][t]);
                }
                printf(" %d\n",b[k]);
                break;
            }
        }
    }

    return 0;
}

scanf("%s %d %d", &s[i], &a[i], &b[i]); 这里注意是%s, 第一次提交因为弄错成了%c而导致错误。

答案2

map方式

#include <iostream>
#include <map>
#include <string>
#include <cstdio>

using namespace std;

struct node{
    string sno;
    int num;
}stu;

map<int, node> mp;

int main(){
    int t;
    cin>>t;
    int k = 0;
    while(t--){
        cin>>stu.sno;
        scanf("%d %d", &k, &stu.num);
        mp[k] = stu;
    }
    int m;
    cin>>m;
    for(int i = 0; i < m; i++){
        int x;
        cin>>x;
        cout<<mp[x].sno<<" "<<mp[x].num<<endl;
    }
    return 0;
}

L1-006 连续因子 (20分)

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

输入格式:

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

输出格式:

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

输入样例:

630

输出样例:

3
5*6*7

答案1

暴力解法

N<23, 因此N介于12的阶乘和13的阶乘之间,所以我们可以得到的最大的数就是12个连续的数相乘,即12的阶乘。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>

using namespace std;

int main()
{
    int N;
    scanf("%d", &N);
    int n = sqrt(N);
    int j;
    long long int sum;
    for(int len = 11; len > 0; len--){   //长度从11递减,因为1不算,最多只有11个数相乘
        for(int i = 2; i <= n; i++){     //i > sqrt(N)时,sum
            sum = 1;
            for(j = i; j < len + i; j++){   //共乘len次,j的个数为len个
                sum *= j;
                if(sum > N)        //sum > N时,没有必要继续乘下去
                    break;
            }
            if(N % sum == 0){      
                printf("%d\n%d", len, i);     //sum从i开始乘,一直乘到j
                for(int k = i + 1; k < j; k++)
                    printf("*%d", k);
                printf("\n");
                return 0;
            }       
        }
    }
    printf("1\n%d\n",N);    //当N是质数时,由于1不算在内,故只有一个因子是其本身
    return 0;
}

第一次因少了一个return 0, 导致输出了所有可能位数和结果

第二次提交由于for(int i = 2; i <= n; i++) 写成了for(int i = 2; i < n; i++)有错误答案,未全部通过

第三次提交,发现未考虑质数而有一个测试点未通过

答案2

用了cout cin输入输出,并且利用count记录长度,更改了一下判断方法

#include <iostream>
#include <cmath>
#include <cstdio>

using namespace std;

int main(){
    int N, temp;
    cin >> N;
    int count;
    int maxcount = 0;
    int s = 0;
    for(int i = 2; i <= sqrt(N); i++){
        temp = N;
        count = 0;
        int j = i;
        while(temp % j == 0){
            temp /= j++;
            count++;
        }
        if(count > maxcount){
            maxcount = count;
            s = i;
        }
    }
    if(maxcount){
        cout << maxcount << endl;
        for(int i = 0; i < maxcount; i++){
            cout << s+i;
            if(i != maxcount - 1)
                cout << "*";
        }
    }
    else
        cout << "1" <<endl << N;
    return 0;
}

L1-007 念数字 (10分)

输入一个整数,输出每个数字对应的拼音。当整数为负数时,先输出fu字。十个数字对应的拼音如下:

0: ling
1: yi
2: er
3: san
4: si
5: wu
6: liu
7: qi
8: ba
9: jiu 

输入格式:

输入在一行中给出一个整数,如:1234

提示:整数包括负数、零和正数。

输出格式:

在一行中输出这个整数对应的拼音,每个数字的拼音之间用空格分开,行末没有最后的空格。如 yi er san si

输入样例:

-600 

输出样例:

fu liu ling ling

答案1

#include <iostream>
#include <stdio.h>
#include <cstring>

using namespace std;

char s[10][5] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
int maxn = 1010;

int main()
{
    char n[maxn];
    int i = 0;
    while(cin>>n){
        if(n[i] == '-'){
            printf("fu");
            i++;
        }
        int len = strlen(n);
        if(i == 1){                        //是负数
            while((len - 1) != 0){
            printf(" %s",s[n[i]-'0']);
            len--;
            i++;
            }
        }
        else{                          //不是负数
            while((len - 1) != 0){
            printf("%s ",s[n[i]-'0']);
            len--;
            i++;
            }
            printf("%s",s[n[i]-'0']);
        }
    }
    return 0;
}

犯困,判断过程有些复杂了,可以考虑函数式编程,但是空格的处理似乎也还是麻烦呢

答案2

更简单的方法

#include <iostream>

using namespace std;

int main(){
    string c[10] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
    //不设数组, 直接用string输入字符串
    string s;
    cin>>s;
    int len = s.length();           //or strlen()
    int fu = s[0] == '-' ? 1 : 0;
    if(fu)
        cout << "fu";
    for(int i = fu; i < len; i++){        //这里i= fu,根据上一步fu直接给i赋值,比答案1更简单
        if(i == 0){
            cout << c[s[i]-'0'];
            continue;
        }
        cout << " " << c[s[i]-'0'];
    }
    return 0;
}

L1-008 求整数段和 (10分)

给定两个整数AB,输出从AB的所有整数以及这些数的和。

输入格式:

输入在一行中给出2个整数AB,其中 100 A B 100 −100≤A≤B≤100 ,其间以空格分隔。

输出格式:

首先顺序输出从AB的所有整数,每5个数字占一行,每个数字占5个字符宽度,向右对齐。最后在一行中按Sum = X的格式输出全部数字的和X

输入样例:

-3 8 

输出样例:

   -3   -2   -1    0    1
    2    3    4    5    6
    7    8
Sum = 30

答案1

格式错误,可我怎么找不出哪里错误呢???

这个解答是错误的

#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    int n, m;
    scanf("%d %d", &n, &m);
    if(n > m){                  //这里是废话
        int temp = n;
        n = m;
        m = temp;
    }
    int sum = 0;
    int count = 0;
    for(int i = 0; i <= (m - n); i++){
        printf("%5d", n+i );
        sum += (n + i);
        count++;
        if(!(count % 5)){
            printf("\n");
        }
        else if((count % 5) && ((n + i) != m)){  //所以这个判断是错误的
            printf(" ");
        }
    }
    if(count % 5)
            printf("\n");

    printf("Sum = %d", sum);
    return 0;
}

刚刚发现,不需要判断n, m 大小,题目给了大小关系

我换一下方式吧

aaaaa 原来%5d之后就不用加空格了!亏我还各种判断,还以为最只有最后一位才没有空格!

答案2

精简版,去掉了答案1的废话和错误的判断,用了cin和cout

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int main(){
    int i, j, m, n;
    cin >> m >> n;
    int count = 0;
    int sum = 0;
    for(i = m; i <= n; i++){
        count++;
        sum += i;
        printf("%5d", i);
        if(count % 5 == 0 && i != n)
            printf("\n");
    }
    cout << endl;
    cout << "Sum = " << sum << endl;
    return 0;
}

L1-009 N个数求和 (20分)

本题的要求很简单,就是求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

最小公倍数和最大公约数求法

//最小公倍数=两整数的乘积÷最大公约数

//辗转相除法
/*
1. a % b 得余数 c
2. if c == 0, 则 b 为最大公约数
3. if c != 0, 则 a = b, b = c 继续执行 1.
*/
#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    int m, n, a, b, c;
    printf("Input two integer numbers:\n");
    scanf("%d%d", &a, &b);
    m = a;
    n = b;
    while(b != 0){
        c = a % b;
        a = b;
        b = c;
    }
    printf("%d\n", a);      //最大公约数
    printf("%d\n", m*n/a);   //最小公倍数
    return 0;
}

//简写
int gcd(int a, int b){
    if(b == 0)
        return a;
    return gcd(b, a % b);
}

//枚举法
int gcd = 1;
for(int k = 2; k <= a && k <= b; k++){
    if(a % k == 0 && b % k == 0)
        gcd = k;
}

//加减法
/*
1. 若a>b,则a=a-b
2. 若a < b,则b=b-a
3. 若a=b,则a(或b)即为两数的最大公约数
4. 若a≠b,则再回去执行1
*/
#include<stdio.h>

int main ( )  /* 相减法求最大公约数 */
{
   int m, n, a, b, c;
   printf("Input two integer numbers:\n");
   scanf ("%d,%d", &a, &b);
   m=a;
   n=b;
   while ( a!=b)
       if (a>b)
           a=a-b;
       else
           b=b-a;
    printf("%d\n", a);     //最大公约数
    printf("%d\n", m*n/a);    //最小公倍数
}

答案1

#include <iostream>
#include <stdio.h>

using namespace std;

long long gcd(long long x, long long y){
    if(x == 0)
        return 0;
    else return (y == 0)? x : gcd(y, x%y);
}

int main()
{
    int n;
    scanf("%d", &n);
    long long a, b, c, d;
    scanf("%lld/%lld", &a, &b);
    int t = gcd(a, b);
    if(t){
        //先给输入的分数约分一下
        a /= t;
        b /= t;
    }
    int i = 1;    //已经输入了一个分数了,故i从1开始
    while(i < n){
        scanf("%lld/%lld", &c, &d);
        long long lcp = b * d/gcd(b, d);   //分母的最小公倍数
        a = a * lcp / b + c * lcp / d;
        b = lcp;
        t = gcd(a, b);    //一边加一边约分
        if(t){
            a /= t;
            b /= t;
        }
        i++;
    }
    if(a && a / b == 0)    //真分数
        printf("%lld/%lld\n", a%b, b);
    else if(!(a % b))    //整数
        printf("%lld\n", a/b);
    else
        printf("%lld %lld/%lld\n", a / b, a % b, b);
    return 0;
}

答案2

结构体的方法

#include <iostream>
#include <algorithm>

using namespace std;

struct node{
    long long fz;
    long long fm;

}frac[110];

int main(){
    int n;
    cin >> n;
    char c;   //存输入的“/”号
    int sum = 1;
    int s = 0;   //总的分子的和
    for(int i = 0; i < n; i++){
        cin >> frac[i].fz >> c >> frac[i].fm;
        sum *= frac[i].fm;      //公共分母, 不知道会不会出现特别大的分母,看看能不能通过,再说
    }
    for(int i = 0; i < n; i++){
        int num  = frac[i].fz;
        for(int j = 0; j < n; j++){
            if(i != j)   //用分子去乘其他所有的分母
                num *= frac[j].fm;
        }
        s += num;
    }
    if(s == 0)                //0
        cout << "0" << endl;
    else if(s % sum == 0)     //整数
        cout << s/sum << endl;
    else{
        if(s / sum >= 1){     //假分数
            int a = s / sum;
            s %= sum;
            int gcd = __gcd(s, sum);
            cout << a << " " << s / gcd << "/" << sum / gcd << endl;
            //这里用scanf好了,cout有点麻烦,同除gcd约分
        }
        else{
            int gcd = __gcd(s, sum);
            cout << s / gcd << "/" << sum / gcd << endl;
        }
    }
    return 0;
}

用了内置的__gcd()函数 #algorithm

L1-010 比较大小 (10分)

本题要求将输入的任意3个整数从小到大输出。

输入格式:

输入在一行中给出3个整数,其间以空格分隔。

输出格式:

在一行中将3个整数从小到大输出,其间以“->”相连。

输入样例:

4 2 8  

输出样例:

2->4->8

答案

#include <iostream>
#include <algorithm>
#include <math.h>
#include <stdio.h>

using namespace std;

int main()
{
    int a, b, c;
    cin >> a >> b >> c;
    int x = max(max(a,b),max(b,c));
    if(x == b){
        b = a;
        a = x;
    }else if(x == c){
        c = a;
        a = x;
    }
    int y = max(b, c);
    if(y == c){
        c = b;
        b = y;
    }
    printf("%d->%d->%d", c, b, a);

    return 0;
}

或许可能上述判断过程复杂了点,不过似乎也没复杂到哪里去emm就这样

总看错题哎,以为从大到小的顺序,用了max(), 还好后面输出把a , c 换一下位置就好

NEXT

L1-011 A-B (20分)

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

输入格式:

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

输出格式:

在一行中打印出 AB 的结果字符串。

输入样例:

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

输出样例:

I lv GPLT!  It's  fn gm!

答案

对B中出现的字符进行标记,输出无标记的即可

#include <iostream>
#include <stdio.h>

using namespace std;

int maxn = 10010;

int main()
{
    char s[maxn], c;
    int a[256] = {0};
    int i = 0;
    fgets(s, maxn, stdin);     //gets(s);  这个用不了
    while((c = getchar())!= '\n')
        a[c] = 1;
    while(s[i] != 0)
    {
        if(!a[s[i]])
            putchar(s[i]);
        i++;
    }
    //cout << endl; 不可以换行 会格式错误
    return 0;
}

L1-012 计算指数 (5分)

真的没骗你,这道才是简单题 —— 对任意给定的不超过 10 的正整数 n,要求你输出 2n。不难吧?

输入格式:

输入在一行中给出一个不超过 10 的正整数 n

输出格式:

在一行中按照格式 2^n = 计算结果 输出 2n 的值。

输入样例:

5

输出样例:

2^5 = 32 
#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    int n;
    cin >> n;
    int sum = 1;
    for(int i = 0; i < n; i++){
        sum *= 2;
    }
    printf("2^%d = %d", n, sum);
    return 0;
}

L1-013 计算阶乘和 (10分)

对于给定的正整数 N N ,需要你计算 S = 1 ! + 2 ! + 3 ! + . . . + N ! S=1!+2!+3!+...+N!

输入格式:

输入在一行中给出一个不超过10的正整数 N

输出格式:

在一行中输出S的值。

输入样例:

3

输出样例:

9

答案

#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    int n;
    cin >> n;
    int sum = n;
    for(int i = n-1; i >= 1; i--){
        sum = ( i *(1 + sum));
    }
    cout << sum << endl;

    return 0;
}

L1-014 简单题 (5分)

这次真的没骗你 —— 这道超级简单的题目没有任何输入。

你只需要在一行中输出事实:This is a simple problem. 就可以了。

输入样例:

输出样例:

This is a simple problem.

答案

#include <iostream>

using namespace std;

int main()
{
    cout << "This is a simple problem." << endl;
    return 0;
}

L1-015 跟奥巴马一起画方块 (15分)

美国总统奥巴马不仅呼吁所有人都学习编程,甚至以身作则编写代码,成为美国历史上首位编写计算机代码的总统。2014年底,为庆祝“计算机科学教育周”正式启动,奥巴马编写了很简单的计算机代码:在屏幕上画一个正方形。现在你也跟他一起画吧!

输入格式:

输入在一行中给出正方形边长N(3≤N≤21)和组成正方形边的某种字符C,间隔一个空格。

输出格式:

输出由给定字符C画出的正方形。但是注意到行间距比列间距大,所以为了让结果看上去更像正方形,我们输出的行数实际上是列数的50%(四舍五入取整)。

输入样例:

10 a

输出样例:

aaaaaaaaaa
aaaaaaaaaa
aaaaaaaaaa
aaaaaaaaaa
aaaaaaaaaa

答案

#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    int n;
    char c;
    scanf("%d %c", &n, &c);
    int N = n;
    if(n % 2)
        N = n + 1;
    for(int i = 0; i < N/2; i++){
        for(int j = 0; j < n; j++){
            printf("%c", c);
        }
        if(i != N/2-1)
            printf("\n");
    }
    return 0;
}

L1-016 查验身份证 (15分)

一个合法的身份证号码由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

答案1

#include <iostream>
#include <stdio.h>
#include <sstream>
#include <string>

using namespace std;

int main(){
    int n;
    cin >> n;
    char m[11] = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
    int q[17] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
    int sum = 0;
    
    string id;
    int x = n;
    while(n--){
        int flag = 0;    //注意这个flag要设在while循环内
        cin >> id;
        for(int i = 0; i < 17; i++){
            if(id[i] < '0' || id[i] > '9'){
                cout << id << endl;
                flag = 1;
                break;
            }
        }
        int s = 0;
        if(!flag){
            for(int i = 0; i < 17; i++){
                int p;
                stringstream convert;
                convert << id[i];
                convert >> p;
                s += p*q[i];
            }
            s %= 11;
            if(m[s] == id[17])
                sum ++;     //记录通过数
            else
                cout << id << endl;
        }

    }
    if(sum == x)
        cout << "All passed" << endl;
    return 0;
}

stringstream

stringstream 是 中定义的类,流的输入输出操作。

主要用来进行数据类型转换

int 转化为string

#include <string>
#include <sstream>
#include <iostream>
#include <stdio.h>

using namespace std;

int main(){
    stringstream convert;
    string str;
    int n = 1234;
    convert << n;   //int 类型放入输入流中
    convert >> str;  //赋给string类型
    cout << str << endl;
    prinf("%s\n", str.c_str());
    return 0;
}

字符串拼接

#include <string>
#include <sstream>
#include <iostream>

using namespace std;

int main(){
    stringstream convert;
    convert << "abc";      
    convert << "opq";                 //拼接后
    cout << convert.str() << endl;    //str方法将stringstream类型转化为string类型

    convert.str("");                  //清空
    convert << "xyz";
    cout << convert.str() << endl;    //清空后重新赋

    return 0;
}

答案2

这个答案来源于网上,不过找不到是哪位写的了QAQ

#include <iostream>
#include <string>

using namespace std;

bool func(string s){
    int sum = 0;
    int a[18];
    for(int i = 0; i < 17; i++){
        if(!isdigit(s[i])){        //isdigit是计算机C(C++)语言中的一个函数,主要用于检查其参数是否为十进制数字字符。
            cout << s << endl;
            return true;   //这里原代码写的是 return false, 我怎么觉得应该是true? 但是不管是true or false 都通过了测试点...
        }
        a[i] = s[i] - '0';
    }
    if(s[17] == 'X')
        a[17] = 10;
    else
        a[17] = s[17] - '0';

    int b[17] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
    for(int i = 0; i < 17; i++){
        sum += a[i]*b[i];   //原代码是sum = sum +, 用 += 更简洁
    }
    sum %= 11;
    int c[11] = {1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2};
    if(c[sum] != a[17]){
        for(int i = 0; i < 17; i++){
            cout << s[i];
        }
        if(a[17] != 10)
            cout << a[17] << endl;
        else{
            cout << "X" << endl;
        }
        return true;
    }
    else{
        return false;
    }
}

int main(){
    int n;
    int count = 0;
    cin >> n;
    for(int i = 0; i < n; i++){
        string a;
        cin >> a;
        if(func(a))
            count ++;
    }
    if(count == 0)
        cout << "All passed";
    return 0;
}

L1-017 到底有多二 (15分)

一个整数“犯二的程度”定义为该数字中包含2的个数与其位数的比值。如果这个数是负数,则程度增加0.5倍;如果还是个偶数,则再增加1倍。例如数字-13142223336是个11位数,其中有3个2,并且是负数,也是偶数,则它的犯二程度计算为:3/11×1.5×2×100%,约为81.82%。本题就请你计算一个给定整数到底有多二。

输入格式:

输入第一行给出一个不超过50位的整数N

输出格式:

在一行中输出N犯二的程度,保留小数点后两位。

输入样例:

-13142223336

输出样例:

81.82%

答案

#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

int main()
{
    char str[55];
    cin >> str;
    //printf("%c", str[3]);
    double h = 1;
    int a = 0, b = 0;     //a表示总长度, b表示2的个数
    if(str[0] == '-'){        //是否是负数
        h *= 1.5;
        a = strlen(str) - 1;
    }
    else{
        a = strlen(str);
    }
    if((str[strlen(str)-1] - '0')%2 == 0)   //只需看最后一位是否是偶数
        h *= 2;
    for(int i = 0; i < strlen(str); i++){
        if(str[i] == '2'){
            b++;
        }
    }
    double sum = h * b * 1.0 / a * 100;    //注意转化为浮点数
    printf("%.2f%%\n", sum);   //转义

    return 0;
}

L1-018 大笨钟 (10分)

微博上有个自称“大笨钟V”的家伙,每天敲钟催促码农们爱惜身体早点睡觉。不过由于笨钟自己作息也不是很规律,所以敲钟并不定时。一般敲钟的点数是根据敲钟时间而定的,如果正好在某个整点敲,那么“当”数就等于那个整点数;如果过了整点,就敲下一个整点数。另外,虽然一天有24小时,钟却是只在后半天敲1~12下。例如在23:00敲钟,就是“当当当当当当当当当当当”,而到了23:01就会是“当当当当当当当当当当当当”。在午夜00:00到中午12:00期间(端点时间包括在内),笨钟是不敲的。

下面就请你写个程序,根据当前时间替大笨钟敲钟。

输入格式:

输入第一行按照hh:mm的格式给出当前时间。其中hh是小时,在00到23之间;mm是分钟,在00到59之间。

输出格式:

根据当前时间替大笨钟敲钟,即在一行中输出相应数量个Dang。如果不是敲钟期,则输出:

Only hh:mm.  Too early to Dang.

其中hh:mm是输入的时间。

输入样例1:

19:05

输出样例1:

DangDangDangDangDangDangDangDang   

输入样例2:

07:05   

输出样例2:

Only 07:05.  Too early to Dang.

答案

#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    int hh, mm;
    scanf("%d:%d", &hh, &mm);
    if(hh < 12 || (hh == 12 && mm == 00)){
        printf("Only %02d:%02d.  Too early to Dang.", hh, mm);
    }
    else{
        if(mm){
            for(int i = 0; i <= hh - 12; i++){
                printf("Dang");
            }
        }
        else{
            for(int i = 0; i < hh - 12; i++){
                printf("Dang");
            }
        }
    }
    return 0;
}

CS 61A 函数式编程

void print(int hh){
    for(int i = 0; i < hh - 12; i++){
        printf("Dang");
    }
}

print(hh);
print(hh + 1);

L1-019 谁先倒 (15分)

划拳是古老中国酒文化的一个有趣的组成部分。酒桌上两人划拳的方法为:每人口中喊出一个数字,同时用手比划出一个数字。如果谁比划出的数字正好等于两人喊出的数字之和,谁就输了,输家罚一杯酒。两人同赢或两人同输则继续下一轮,直到唯一的赢家出现。

下面给出甲、乙两人的酒量(最多能喝多少杯不倒)和划拳记录,请你判断两个人谁先倒。

输入格式:

输入第一行先后给出甲、乙两人的酒量(不超过100的非负整数),以空格分隔。下一行给出一个正整数N(≤100),随后N行,每行给出一轮划拳的记录,格式为:

甲喊 甲划 乙喊 乙划

其中是喊出的数字,是划出的数字,均为不超过100的正整数(两只手一起划)。

输出格式:

在第一行中输出先倒下的那个人:A代表甲,B代表乙。第二行中输出没倒的那个人喝了多少杯。题目保证有一个人倒下。注意程序处理到有人倒下就终止,后面的数据不必处理。

输入样例:

1 1
6
8 10 9 12
5 10 5 10
3 8 5 12
12 18 1 13
4 16 12 15
15 1 1 16

输出样例:

A
1

答案

#include <iostream>

using namespace std;

int main()
{
    int ja, jb;
    cin >> ja >> jb;
    int a = ja, b = jb;
    int n;
    cin >> n;
    for(int i = 0; i < n; i++){
        int ha, hb, hua, hub;
        cin >> ha >> hua >> hb >> hub;
        if(hua == (ha + hb) && hub == (ha + hb))  //第一次提交忘记了判断两人同输的情况
            continue;
        else{
            if(hua == (ha + hb))
                ja--;
            if(hub == (ha + hb))
                jb--;
            if(ja < 0){    //第二次发现这里不是 == 0 而是 < 0 才算喝醉 (′⌒`)
                cout << "A" << endl << b - jb;
                return 0;
            }
            else if(jb < 0){
                cout << "B" << endl << a - ja;
               return 0;
            }
        }

    }

    return 0;
}

L1-020 帅到没朋友 (20分)

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

输入格式:

输入第一行给出一个正整数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 <iostream>
#include <stdio.h>

using namespace std;

int id[100010] = {0};
//int flag[100010] = {0};   没用上

int main()
{
    int n;
    cin >> n;
    for(int i = 0; i < n; i++){
        int m;
        cin >> m;    //*
            for(int j = 0; j < m; j++){
                int i;
                cin >> i;
                if(m != 1)   //第一次忘记判断m是否等于1, 第二次将 m != 1放在了*位置,导致输入错误了
                   id[i] = 1;
            }
    }
    int c;
    int count = 0;
    cin >> c;
    for(int i = 0; i < c; i++){
        int x;
        cin >> x;
        if(id[x] != 1){
            id[x] = 1;    //&
            if(count == 0)
                printf("%05d", x);    //第一次空格输入不对, 第二次数字格式错误了
                //cout << x ;
            else
                printf(" %05d", x);
                //cout << " " << x;
            count++;            //还有一次把count++放在了&这里,出错了qaq
        }
    }
    if(!count)
        cout << "No one is handsome" ;
    return 0;
}

这个答案最后一个测试点用了80ms,而AC的答案里有20ms以内的,分析原因,其实是cin和scanf, cout 和 printf 的速度问题,cin 和cout 普遍慢于 scanf 和 printf。(这题能看出来真的慢了好多啊…)

害,改了N遍,咸鱼一条,基础先做到这里,赶快捡起我的数据结构吧,树图马上就忘光了…

发布了44 篇原创文章 · 获赞 0 · 访问量 1319

猜你喜欢

转载自blog.csdn.net/qq_41664688/article/details/104142960