计蒜客题目 计数和数数

“伯爵说”序列如下:1,11,21,1211,111221, \ldots1,11,21,1211,111221,。其1读作one 1或者1111读作two 1s或者2121读作one 2, one 1或者1211

输入格式

多组输入,读到文件结束。每组输入给定一个整数 n(1 \leq n \leq 30)n(1n30)

输出格式

输出第 nn 个序列。注意,整数序列以字符串的形式表示。

样例输入
6
样例输出
312211
#include<string.h>
#include<stdlib.h>
#include<iostream>

using namespace std;

void convert(char *s)
{
    unsigned long size=strlen(s);
    char digit[size];
    int fre[size];
    digit[0]=s[0];//digit的首位初始化
    fre[0]=1;//fre的首位初始化
    int k=0;//k是digit的数字个数
    for(int i=1;i<size;i++){
        if(s[i]==s[i-1]){//这个字符和上一个字符相同
            fre[k]++;
        }
        else{//不相同,则保存字符,并且记录次数为1
            k++;
            digit[k]=s[i];
            fre[k]=1;
        }
    }
    for(int i=0;i<size;i++) s[i]='\0';
    for(int i=0;i<=k;i++){
        s[2*i]=fre[i]+'0';
        s[2*i+1]=digit[i];
    }

}

int main()
{    
    int n;
    while(cin>>n){
        char s[10000]={'1'};
        for(int i=0;i<n-1;i++) {
            convert(s);
        }
        cout<<s<<endl;
    }
    
    return 0;
}

思路:写出变换的函数:从前向后遍历数组,用digit保存此时遍历到的数字,用fre保存这个数字出现的次数。每次遍历都与前一个字符比较,若字符相同,则fre++,否则digit保存新的字符,对应的新fre为1。在main函数中,根据输入的n,处理n-1次“1”即可。

总结:

这道题花费了特别久的时间……遇到了很多问题。

1、我最初的思路是用一个f数组保存1~30以内所有的“伯爵说”数字,然后根据n对应输出,但是提示超时或者栈溢出。后来改进,每次都对上次的做变换,这样只要保存两个数字即可,解决了这个问题。

2、我用string &s作为convert函数的输入变量,用s+=fre和s+=digit来保存字符,仍然提示栈溢出,只能保存1~7之内的数字。因为这个问题花费了很长时间,后来思考可能是因为+=表示将字符并在原先字符之后,原先的字符空间没有释放,这样占了非常多的内存所以没通过。但是使用s.empty()或者对s[i]='\0',都没有解决这个问题。没有办法。参考了其他人的代码后,将string类型改为了char *作为convert函数的输入变量,不使用+=,而是对每个字符用fre和digit赋值。解决了这个问题。

3、在main函数里面,char s[10000]的申明我放在了while语句之外,尽管在每次cout<<s后都对s重新初始化,仍然没有得到理想的结果,不知道原因出在哪里,只好把char s[10000]的申明放在了while之内,解决了这个问题。

唉,感觉我的基础知识还是非常匮乏的,大一学的C++都忘的干干净净的了,还自信地没带回来书。等回学校了要看C++的书。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值