外观数列是指具有以下特点的整数序列:
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 项。输入格式:
输入第一行给出 [0,9] 范围内的一个整数
d
、以及一个正整数 N(≤ 40),用空格分隔。输出格式:
在一行中给出数字
d
的外观数列的第 N 项。输入样例:
1 8
输出样例:
1123123111
一开始拿到这题没看懂,拿笔模拟都模拟不出来...后来读了好几遍题,才能用笔写出来。
以题目中的d = 1为例:前8项分别是
1 11 12 1121 122111 112213 12221131 1123123111
这是第一步,如果你用笔模拟不出来,那就多读题,直到能独立写对这8项时再往下看代码。
题解:
用字符串s存初始数字d。
最外层循环:为什么循环到n-1?因为从第一项开始。求第二项需计算1次,求第n项,则计算n-1次。
第二个循环:遍历字符串。(先别管为什么是i = j)
第三个循环:从当前位置s[i]开始,往后数有多少连续、且相同的字符的个数。
for(j = i; j < s.size() && s[i] == s[j]; ++j) { ; } // 这个for循环是空语句,j 用来计数。
t += s[i] + to_string(j - i);
变量 j 从当前位置 i 开始,如果与s[i]值相同就往后走,不同就停。 差值(j - i)就是与s[i]相同的字符个数。
第二个循环中的 i = j 是跳过中间连续相同的字符,从第一个不同的位置开始。
#include <iostream>
using namespace std;
int main(){
string s;
int n, j;
cin >> s >> n;
for(int k = 0; k < n - 1; ++k){
string t;
for(int i = 0; i < s.size(); i = j){
for(j = i; j < s.size() && s[i] == s[j]; ++j); //注意分号!这个for循环是空语句。
t += s[i] + to_string(j - i);
}
s = t;
}
cout << s;
return 0;
}