1084 外观数列

1084 外观数列

分数 20
作者 CHEN, Yue
单位 浙江大学

外观数列是指具有以下特点的整数序列: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
②:第二项是对第一项的描述,形式为:因为第一项有一个d,所以第二项为d1(前面是某个数字,后面是这个数字出现的次数)
③:第三项是对第二项的描述,形式为:因为第二项有一个d,一个1,所以第三项为d1 11
④:第四项是对第三项的描述,形式为:因为第三项有一个d,三个1,所以第四项为d1 13
⑤:……
理解好题目就可以写代码了,我们生命两个数组,不停的迭代,首先a数组第一项肯定是输入的数字,注意要用字符类型接收,然后迭代n-1次之后就是第n个数组,首先对比a和b数组,以b数组为主,比较有相同的元素记录出现次数,然后更新b数组的值,一次循环之后b数组已经是某一次的最终结果,然后记录当前数组长度,并且将b数组拷贝到a数组,继续迭代,最终输出即可
————————————————
版权声明:本文为CSDN博主「IronmanJay」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/IronmanJay/article/details/123371221

  • 这道题不太好理解,我建议在纸上推导一下。借鉴的jay哥的代码。
  • a b 两个数组内容是相同的,不过 b 数组是用来固定判断的,是会改变的,a数组是用来枚举的。最后再把b赋值给a。
    b[index]不变然后a枚举count增加直到 a b 不相同。此时把count给b[++index]赋值,再把a[j]赋值给b[++index]然后再次枚举。
  • 用 index 可以控制 b 的下标,也可以知道数字有多长,赋值给 len 供下一回用,符合题意。

错误分析:

#include<stdio.h>

int main(){
	int d;
	int n;
	int a[42][10000] = {0};
//	for(int i = 0; i < 40;i++){
//		for(int j = 0; j < 1000;j++){
//			a[i][j] = -1;
//		}
//	} 
	scanf("%d%d",&d,&n);
	a[0][0] = d;//第一项 
	int len = 1;
	int tmp = 0;//存放当前数字 
	for(int i = 0; i < n; i++){
		int j = 0;//每一项都重新开始 
		int k = 0;//控制后一项的列 
		while(a[i][j]!=0){
			tmp = a[i][j]; 
			a[i+1][k++] = tmp; 
			int times = 0;//每个数字连续出现多少次
			while(a[i][j] == tmp){
				j++;
				times++;
			} 
			a[i+1][k++] = times;
		}
		
	}
		
		int j = 0;
		while(a[n-1][j]!=0){
			printf("%d",a[n-1][j++]);
		}
	
		
}

这是我原本的写法,测试点4一直过不去。我觉得主要原因主要有两个,一个就是三重循环太费时间,再一个就是用的二维数组规模大费时间。数字根本没必要保存。
如果要先赋值为 -1 的话就导致n =25 就超时。如果不赋值,还是有错。

代码实现:

#include<stdio.h>
#include<string.h>
int main(){
	int n;
	char d;
	scanf("%c %d",&d,&n);
	char a[100000];
	char b[100000];
	int len = 1;
	a[0] = d;
	for(int i = 1; i < n; i++){
		int count = 0;//每个数字的次数 
		int index = 0;//b用的下标
		b[0] = a[0];//b先赋值为数 
		for(int j = 0; j <= len; j++){
			if(a[j] == b[index]){
				count++;
			}
			else{
				b[++index] = count + '0';//b下一个赋值为次数 
				//先用后加是因为0号位已经赋值了 
				b[++index] = a[j];//b下一个赋值为数,b被改动了,用a的 
				count = 1; //既然已经赋值了,那么数量至少是1. 
			} 
		}
		len = index;//重新赋值长度 
		strcpy(a,b);//b给a,现在a b一样,b固定住,a增加 
	}
	printf("%s",a);
	 
}

参考:

【PAT (Basic Level) Practice】——【简单模拟】1084 外观数列

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值