中国大学MOOC-陈越、何钦铭-数据结构-起步能力自测题

自测-4 Have Fun with Numbers
Notice that the number 123456789 is a 9-digit number consisting exactly the numbers from 1 to 9, with no duplication. Double it we will obtain 246913578, which happens to be another 9-digit number consisting exactly the numbers from 1 to 9, only in a different permutation. Check to see the result if we double it again!

Now you are suppose to check if there are more numbers with this property. That is, double a given number with k digits, you are to tell if the resulting number consists of only a permutation of the digits in the original number.
Input Specification:
Each input contains one test case. Each case contains one positive integer with no more than 20 digits.
Output Specification:
For each test case, first print in a line “Yes” if doubling the input number gives a number that consists of only a permutation of the digits in the original number, or “No” if not. Then in the next line, print the doubled number.
Sample Input:

1234567899

Sample Output:

Yes
2469135798

分析

  1. 读入输入的整数

  2. 统计该整数中0-9各出现了几次

  3. 将该整数乘2再判断0-9出现的次数
    一开始我以为判断0-9出现的次数是本题的核心,写成函数复用就可以,但很快发现C语言函数返回值不可以是数组,只好作罢。而且读入的时候也没有我想象的容易,因为无符号整数仍然不能存储20位的数字,所以只好采用字符数组来保存输入的值。也用过gets但是编译器好像不喜欢他,有warning,最终仍然采用scanf来读数据。
    实际的步骤应该是这样的:

    1. 使用字符数组读入数据,并用strlen函数获得数据的位数
    2. 统计该数中0-9出现的次数,存为数组a
    3. 按位每一位都乘2,其中涉及到进位的问题,得到一个新的数组
    4. 统计新数组中0-9出现的次数,存为数组b
    5. 循环比较两个数组a和b,若全相同则符合,否则不符
      具体的C语言实现程序如下:
#include<stdio.h>
#include<string.h>
int main()
{
	int i,j;//定义循环变量
	int a[10]={0};
	int b[10]={0};
	char str[20];//定义一个20位长的字符数组用于接收输入的数
	int str2[21]={0};//定义一个21位长的字符数组用于保存乘2的数 
	int returnValue;//声明scanf的返回值 
	returnValue = scanf("%s",str);//读入这个数,存到字符数组中 
	int len = strlen(str);//用strlen函数求字符串长度,即输入数字的位数
	int result=0;//用于保存重复数字的个数 
	
	//先处理scanf的返回值
	if(returnValue==1){
		/*统计第一个数中出现了0-9数字的次数*/
		for(i=0;i<=len-1;i++){			//从第一位开始统计 
			for(j=0;j<=9;j++){			//针对数据中的每一位从0开始比较  
				if(str[i]-'0'==j){		//如果这一位数字和0-9中的一个 
					a[j]++;				//相应的计数数组元素加1 
				}
			}
		}
		
		/*将第一个数乘2并存为整型数组*/
		for(i=len-1;i>=0;i--){
			//分为进位和不进位两种 
			if(str[i]-'0'>=5){
				str2[i+1]+=(str[i]-'0')*2%10;
				str2[i]++;
			}else{
				str2[i+1]+=(str[i]-'0')*2;
			}
		}
		
		/*统计第二个数中出现了0-9数字的次数*/
		/*如果最高位进位从第一位开始数
		  如果最高位没进位从次高位开始数 
		*/
		if(str2[0]==1){
			for(i=0;i<=len;i++){			//从第一位开始统计,注意比第一个数多了一位 
				for(j=0;j<=9;j++){			//针对数据中的每一位从0开始比较  
					if(str2[i]==j){		//如果这一位数字和0-9中的一个 
						b[j]++;				//相应的计数数组元素加1 
					}
				}
			}	
		}else{
			for(i=1;i<=len;i++){			//从次高位开始统计,注意比第一个数多了一位 
				for(j=0;j<=9;j++){			//针对数据中的每一位从0开始比较  
					if(str2[i]==j){		//如果这一位数字和0-9中的一个 
						b[j]++;				//相应的计数数组元素加1 
					}
				}
			}
		}
		
		for(i=0;i<=9;i++){
			if(a[i]==b[i]){
				result++;
			}
		}
		//如果a,b两个数组全都一样则符合要求 
		if(result==10){
			printf("Yes\n");
		}else{
			printf("No\n");
		}
		//循环打印第二个数 
		if(str2[0]==1){
			for(i=0;i<=len;i++){			
				printf("%d",str2[i]);		
			}	
		}else{
			for(i=1;i<=len;i++){			
				printf("%d",str2[i]);
			}
		}
	}else{
		printf("输入错误");
	}
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值