PTA刷题笔记(C语言) | 7-49 Have Fun with Numbers (20分)

开始刷题,感觉代码量和基础太渣了,导致数据结构不会,重头慢慢刷吧~
在这里插入图片描述


1、题目

在这里插入图片描述
Sample Input:

1234567899

Sample Output:

Yes
2469135798


译文:

注意,编号123456789是一个9位数字,由1到9之间的数字组成,没有重复。加倍我们将得到246913578,这恰好是另一个9位数的数字,由1到9的数字组成,只是排列不同。如果我们再加倍检查一下结果!

现在您应该检查这个属性是否有更多的数字。也就是说,把一个给定的数字乘以两倍,再加上k个数字,你就可以知道得到的数字是否只由原始数字中的数字排列而成。

输入规格:

每个输入包含一个测试用例。每个大小写包含一个不超过20位的正整数。

输出规格:

对于每一个测试用例,如果输入的数字加倍,则第一次在“是”行中打印一个数字,该数字仅由原始数字中的数字排列而成,否则为“否”。然后在下一行中,打印加倍的数字。


2、代码

#include <stdio.h>
#include <string.h>
int main (){
    char start[21];
    char end[21];
    gets(start);	//输入数
    int t,i,j,m=0,s;
    t=strlen(start);	//存入数的长度即位数
    int flag1=1;
    //第一位数字大于5要进位,字符运算
    if((start[0]-'0')*2>=10){
        end[0]='1';		//乘2进位只可能为1
        flag1=0;		//位数改变则表明一定不同
    }
    //从末尾开始做乘法
    for(i=t-1; i>=0; i--){
    	//有进位
        if((start[i]-'0')*2>=10){
			s=(start[i]-'0')*2%10+m;
            end[i+1]='0'+s;
            m=1;		//进位存储
        }
        //无进位
        else{
            s=(start[i]-'0')*2+m;
            end[i+1]='0'+s;
            m=0;
        }
    }
    int flag=1;
    //在end数组中遍历,若存在两数相等,则在start数组中将此数变为a
    for(i=1; i<=t; i++){ 
        for(j=0; j<t; j++){
            if(end[i]==start[j]){
                start[j]='a';
                break;
            }
        }
    } 
    //若start数组中不全为a,则证明有不同的数产生
    for(i=0; i<t; i++){
        if(start[i]!='a'){
            flag=0;
            break;
        }
    }
    if(flag==1)
        printf("Yes\n");
    else
		printf("No\n");
    if(flag1==0){
    	//进位后输出从第一位开始
        for(i=0; i<=t; i++){
            printf("%c",end[i]);
        }
    }
    else{
    	//无进位从第二位开始
        for(i=1; i<=t; i++){
            printf("%c",end[i]);
        }
    }
    return 0;
 
}

在这里插入图片描述

3、讨论

这个题,由于限制是不超过20位的数字,若采用整形会造成越界问题,别问我怎么知道的,试出来的,哈哈,所以采用字符数组来存储大数并模拟大数的乘2运算。

由于只是乘2运算,进位不是那么复杂,可以只在存储数组前空出一位方便进位即可。

先保存最开始的第一位进位,然后正常计算,如果乘2之后大于等于10,那么进1,否则,不进。

妙啊!!!
在这里插入图片描述
在这里插入图片描述

©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页