团体程序设计天梯赛-练习集L1-051~L1-060

本文提供了一系列程序设计挑战题目,包括汉字倒置输出、比赛胜负判断、猜数字游戏等,旨在提升编程技能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

L1-051


L1-052


L1-053


L1-054. 福到了

“福”字倒着贴,寓意“福到”。不论到底算不算民俗,本题且请你编写程序,把各种汉字倒过来输出。这里要处理的每个汉字是由一个 N × N 的网格组成的,网格中的元素或者为字符 @ 或者为空格。而倒过来的汉字所用的字符由裁判指定。

输入格式:
输入在第一行中给出倒过来的汉字所用的字符、以及网格的规模 N (不超过100的正整数),其间以 1 个空格分隔;随后 N 行,每行给出 N 个字符,或者为 @ 或者为空格。

输出格式:
输出倒置的网格,如样例所示。但是,如果这个字正过来倒过去是一样的,就先输出bu yong dao le,然后再用输入指定的字符将其输出。

输入样例 1:
$ 9
@ @@@@@
@@@ @@@
@ @ @
@@@ @@@
@@@ @@@@@
@@@ @ @ @
@@@ @@@@@
@ @ @ @
@ @@@@@

输出样例 1:
$$$KaTeX parse error: Can't use function '$' in math mode at position 3: $̲ $ $ $ $ $ $
$ $ $ $ $ $
$ $
$ $ $
$ $
$$$$$ $

输入样例 2:
& 3
@@@
@
@@@

输出样例 2:
bu yong dao le
&&&
&
&&&

Note:
没什么好说的,全写在代码里面了。

#include <stdio.h>

int main()
{
    int i, j, k, N, flag = 1;               // 置1表示先默认网格上下对称
    char c, q;
    scanf("%c %d", &c, &N);
    char s[110][110];                       // 逆序将网格中的字符存入二维数组
    for (i = N - 1; i >= 0; i--) {
        getchar();                          // 过滤上一个 scanf 输入后遗留的回车
        for (j = N - 1; j >= 0; j--) {
            scanf("%c", &q);
            if (q == '@') s[i][j] = c;      // 将 @ 换为指定的输出字符
            else s[i][j] = q;
        }
    }

    for (i = 0, j = N - 1; i < j; i++, j--) // 同步进行的变量放在同一个 for 内不要错弄成两层
            for (k = 0; k < N; k++)
                if (s[i][k] != s[j][k])
                    flag = 0;               // 出现不同就标记为0,表示存在不对称的地方


    if (flag) printf("bu yong dao le\n");
    for (i = 0; i < N; i++)                 // 顺序输出二维数组的元素
        for (j = 0; j < N; j++) {
            printf("%c", s[i][j]);
            if (j + 1 == N && i + 1 != N) printf("\n");
        }
    return 0;
}

L1-055. 谁是赢家

某电视台的娱乐节目有个表演评审环节,每次安排两位艺人表演,他们的胜负由观众投票和 3 名评委投票两部分共同决定。规则为:如果一位艺人的观众票数高,且得到至少 1 名评委的认可,该艺人就胜出;或艺人的观众票数低,但得到全部评委的认可,也可以胜出。节目保证投票的观众人数为奇数,所以不存在平票的情况。本题就请你用程序判断谁是赢家。

输入格式:
输入第一行给出 2 个不超过 1000 的正整数 Pa 和 Pb,分别是艺人 a 和艺人 b 得到的观众票数。题目保证这两个数字不相等。随后第二行给出 3 名评委的投票结果。数字 0 代表投票给 a,数字 1 代表投票给 b,其间以一个空格分隔。

输出格式:
按以下格式输出赢家:
The winner is x: P1 + P2
其中 x 是代表赢家的字母,P1 是赢家得到的观众票数,P2 是赢家得到的评委票数。

输入样例:
327 129
1 0 1

输出样例:
The winner is a: 327 + 1

Note:
只要 a 艺人不赢肯定就是 b 艺人赢,所以判断条件一条 if 语句就可以了,注意前面 while 循环,直接令 scanf 语句作为 while 循环的条件就可以了。

#include <stdio.h>

int main()
{
    int pa, pb, n, p = 3;                    // count 统计艺人得到评委的投票数
    int counta  = 0, countb = 0;
    scanf("%d %d", &pa, &pb);

    while (scanf("%d", &n) != EOF) {
        if (n == 0) counta ++;
        else countb ++;
    }
    if ((pa > pb && counta >= 1) || (pa < pb && counta == 3)) printf("The winner is a: %d + %d", pa, counta);
    else printf("The winner is b: %d + %d", pb, countb);
}

L1-056. 猜数字

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

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

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

输入样例:
7
Bob 35
Amy 28
James 98
Alice 11
Jack 45
Smith 33
Chris 62

输出样例:
22 Amy

Note:

1、scanf 是可以同时输入字符串和数字的,如果字符串第一个数字是字符时需要加空格隔开,以免将其读入数字。

2、使用二维字符数组时,如果针对每一行输入字符串,即 s[i] 时,长度是可以超过定义时二维的长度的。举个栗子,你定义 s[10][2],你给 s[1] 输入 asdfe 然后输出,仍然能够输出 asdfe。

3、既然是比价最接近某个值的题目,所以不能忘记加绝对值。

4、注意题目说的是最接近“平均数的一半”才算赢。

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

int main()
{
    int i, N, flag = 0;                         // flag 标记最小位
    double sum, guess[10000];
    char name[10000][9];
    scanf("%d", &N);
    for (i = 0; i < N; i++) {
        scanf("%s %lf", name[i], &guess[i]);    // 防止出错还是要加一个空格
        sum += guess[i];                        // 猜数累加到 sum 中
    }

    double ave = sum/(N*2.0);                   // 把 N 转换为浮点型才能正确运算
    double min = fabs(guess[0] - ave);
    for (i = 1; i <N; i++) {
        if (fabs(guess[i] - ave) < min) {       // 别忘记绝对值
            min = fabs(guess[i] - ave);         // 更新最小值
            flag = i;                           // 更新标记位
        }
    }
    printf("%d %s", (int)ave, name[flag]);
    return 0;
}

后面去看了下柳婼小改改的大佬,发现大佬就是大佬,真的不一般啊。。。链接在下面乃们自己去看一下吧。我是传送门


L1-057


L1-058. 6翻了

在这里插入图片描述
“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

Note:
1、遍历字符数组,遇到6就停下来数6的个数,判定输出,然后直接跳到该段连续6的后一个字符继续往下遍历。自己写一个小小的含有连续6的字符串来试着理解一下,按数组下标标记每一个字符。

2、while 里面放 flag++ 和 ++flag 是有区别的。flag++ 会在判断条件失败之后再增一,此时 flag 标记的是该段连续6的后两个字符,会后一个字符而少输出一个字符;++flag 在 flag 自增到该段连续6的后一个字符时就跳出循环了,然后外循环从 flag 继续遍历,这才是符合题意的。

3、scanf("%[^\n]", s); 的作用是读取除回车外的所有字符,遇到回车后就停止输入。

#include <stdio.h>

int main()
{
    char s[1010];                               // flag 标记连续6结束位置的下一个字符
    int count, flag;                            // count 记录连续6的个数
    scanf("%[^\n]", s);                         // 输入字符串

    for (int i = 0; s[i] != '\0'; i++) {        // 遍历
        if (s[i] == '6') {                      // 读到6停下来
            flag = i;                           // flag 赋初值 i
            while (s[++flag] == '6');           // flag 自增,结束值为该段6后一个字符的下标
            count = flag - i;
            if (count > 3 && count <= 9) printf("9");
            else if (count > 9) printf("27");
            else while(count--) printf("6");    // 不满足条件则把该连续6输出

            if (s[flag] == '\0') break;         // flag 到达字符串结尾则停止遍历
            i = flag;
        }
        printf("%c", s[i]);
    }
    return 0;
}

然后我在网上找到一个用正则表达式写题的。。。emmm没看懂,想看的小伙伴可以自己参考一下。

#include<bits/stdc++.h>
using namespace std;
int main(){
  string s;
  getline(cin, s);
  cout << regex_replace(regex_replace(s, regex("6{10,}"), "27"), regex("6{4,}"), "9");
  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

Note:
1、这题主要花时间在变量写错,怎么调试都只输出一个结果,结果发现是某一次的自增变量写成了 i++ 而不是 j++,所有小伙伴们一定要好好地仔细地检查自己的代码,尤其是那些细节的部分。

2、这题坑点在于,不一定输入的都是七言古诗,有可能是五言,所有数空格时要倒着数而不能正着数。

3、strlen() 函数不能直接测二维数组的,即 strlen(s) 是会出错的,但是 strlen(s[i]) 就是可以的。可以理解为二维字符数组实际上就是存储了多行字符串,同时为每一行都存储了一个行号。

4、连用两个 if 判别式,条件其实是可以写到一个 if 里面的。看到一个博主直接为了省语句直接写进去,其实是很不推荐也没必要为了省一两个语句而增加内存。算法优化的目的就是为了减少内存和运行时间不对吗?而且也容易出错,那样写程序运行过程中会做很多不必要的运算。

5、个人觉得这个算法效率还是很低,有改进的小伙伴欢迎在评论区给我指正一下,看着这么长真的很难受o(TωT)o。

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

int main()
{
    char s[20][110];
    int i, j, N, count, flag, flag1, flag2;
    scanf("%d", &N);
    for (i = 0; i < N; i++) {
        getchar();                                              // 过滤上个 scanf 的回车
        scanf("%[^\n]", s[i]);
    }

    for (i = 0; i < N; i++) {                                   // 逐行遍历
        flag1 = flag2 = count = 0;
        for (j = 0; s[i][j] != '\0'; j++) {                     // 在每一行逐字符遍历
            if (s[i][j] == ',')                                 // 遇到逗号就停下判断;
                if (s[i][j - 3] == 'o' && s[i][j - 2] == 'n' && s[i][j - 1] == 'g')
                    flag1 = 1;
            if (s[i][j] == '.')                                 // 遇到句号就停下判断
                if (s[i][j - 3] == 'o' && s[i][j - 2] == 'n' && s[i][j - 1] == 'g')
                    flag2 = 1;
        }
        if (flag1 && flag2) {                                   // 判断是否押韵,是的话则输出大笨钟
            for (flag = strlen(s[i]) - 1; 1; flag--) {
                if (s[i][flag] == ' ')
                    count ++;                                   // count 统计遇到的空格次数
                if (count == 3)                                 // 在倒数第三个空格退出循环
                    break;
            }
            for (j = 0; j <= flag; j++)
                printf("%c", s[i][j]);
            printf("qiao ben zhong.\n");
        }
        else printf("Skipped\n");                               // 判断为不押则输出跳过
    }
    return 0;
}

L1-060


一定要自己写一遍哦~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值