PAT乙 1084. 外观数列 (20)

题目地址:PAT乙1084.外观数列(20)

题目描述:

外观数列是指具有以下特点的整数序列:d, d1, d111, d113, d11231, d112213111, ...
    它从不等于 1 的数字 d 开始,序列的第 n+1 项是对第 n 项的描述。比如第 2 项表示第 1 项有 1 个 d,所以就是 d1;第 2 项是 1 个 d(对应 d1)和 1 个 1(对应 11),所以第 3 项就是 d111。又比如第 4 项是 d113,其描述就是 1 个 d,2 个 1,1 个 3,所以下一项就是 d11231。当然这个定义对 d = 1 也成立。本题要求你推算任意给定数字 d 的外观数列的第 N 项。

题目解读:

    这道题目说实话题目意思都有点难以理解,我在这简要解释一下。

    1.    d          只有一个d

    2.    d1        因为前面只有一个d,所以这里就写成d1,表示1个d

    3.  d111      这里是在第二个基础上,扩充而来,我在这添上一个辅助的分割符'|'帮助大家理解。那么第二个d1可以写成d|1,这样就分成了前后两个部分,前半部分是d,那么就是“一个d”,写成d1;后半部分是1,就是“一个1”,写成11。所以第三项就是d1|11即d111。

    4.    d113      分成d|111,那么就是“一个d”、“三个1”,第四项就写成d1|13

    5.    d11231 分成d|11|3,那么就是“一个d”、“两个1”、“一个3”。那第五项九尾d1|12|31.

总之一句话,就是把这个字符串进行分割,分割的方法为相同的数字为1块,然后对每一块描述,就是结果。到这里,可能有人已经看懂了我的例子,但发现去测试输入样例好像不对???在这里,我要说的是d用1带的话,第二项就是11,而不是"d1",所以不用分割成1|1,而是把11看成一个整体,这样出来的答案就是对的。

易错分析:

 1.    第五个样例的N应该是40,这时字符数组的长度将很长,需要把数组开的大一点。

 2.    用puts打印比printf快速,不然第五个样例就会超时。

解题过程:

       使用3个数组,其中s为每一项的字符数组,temp2为每一个分段的结果,temp用于连接temp2所对应的结果。用strcpy对数组重新赋值,用strcat连接数组,即可。

程序:

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

int main(int argc, char const *argv[])
{
    int N;  
    char s[100000], temp[100000], temp2[100000];   
    scanf("%c %d", &s[0], &N);
    for (int i = 0; i < N-1; i++)
    {   /* cnt计算重复字母出现的次数 */
        int len = strlen(s), cnt = 1;
        for (int k = 0; k < len; k++)
        {   /* 因为s[len]处为'\0',所以不用担心越界 */
            if (s[k] == s[k+1])
                cnt++;  // 如果前后相等cnt++
            else
            {   /* 连接字符和次数 */
                temp2[0] = s[k];
                temp2[1] = cnt + '0';
                strcat(temp, temp2); 
                cnt = 1;
            }         
        }
        strcpy(s, temp);
        memset(temp, '\0', sizeof(temp));    // 清空temp
    }
    puts(s);    // 使用puts比printf更高效,用printf第五个样例超时
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值