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,否则,不进。
妙啊!!!
还没有评论,来说两句吧...