问题描述
给定任一个各位数字不完全相同的 4 位正整数,如果我们先把 4 个数字按非递增排序,再按非递减排序,然后用第 1 个数字减第 2 个数字,将得到一个新的数字。一直重复这样做,我们很快会停在有“数字黑洞”之称的 6174,这个神奇的数字也叫 Kaprekar 常数。
例如,我们从6767开始,将得到
7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
7641 - 1467 = 6174
… …
现给定任意 4 位正整数,请编写程序演示到达黑洞的过程。
输入格式:
输入给出一个 (0,10^(4))区间内的正整数 N。
输出格式:
如果 N 的 4 位数字全相等,则在一行内输出 N - N = 0000;否则将计算的每一步在一行内输出,直到 6174 作为差出现,输出格式见样例。注意每个数字按 4 位数格式输出。
输入样例 1:
6767
输出样例 1:
7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
输入样例 2:
2222
输出样例 2:
2222 - 2222 = 0000
思路
输入数字->转换为字符串->排序->排序后记录下对应的整数型->最大减最小得到最后结果->结果转换为字符串打印->字符串转换为数字继续循环
AC代码1(使用字符串)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
void intTostr(char s[],int a)
{
int b;
for(int i=0;i<4;i++)
{
b=a%10;
b+=48;//0的ascii码为48;
s[3-i]=b;
a/=10;
}
}
int compare1(const void*a,const void*b)
{//从小到大排序
char* pa=(char*)a;//pa 前的char*不允许带括号
char* pb=(char*)b;
return (*pa)>(*pb)?1:-1;
}
int compare2(const void*a,const void*b)
{//从大到小排序
char* pa=(char*)a;
char* pb=(char*)b;
return (*pb)>(*pa)?1:-1;
}
int strToint(char s[])
{
int sum=0,now=1;
for(int i=0;i<4;i++)
{
sum+=now*(s[3-i]-48);
now*=10;
}
return sum;
}
int main()
{
//freopen("input.txt","r",stdin);//用于读入input.txt中的数据
//freopen("output.txt","w",stdout);//用于将输出结果写到output.txt中,cmd窗口中不显示结果
char s[4];
int num;
int a,b,c;
scanf("%d",&num);
while(1)
{
intTostr(s,num);
qsort(s,4,1,compare2);
printf("%s",s);
a=strToint(s);
qsort(s,4,1,compare1);
printf(" - %s = ",s);
b=strToint(s);
c=a-b;
if(c==0)
{
printf("0000");
break;
}
else if(c==6174)
{
printf("6174");
break;
}
intTostr(s,c);
for(int j=0;j<4;j++)printf("%c",s[j]);//这里用puts(s);会出现其他字符,不解
printf("\n");
num=strToint(s);
}
}
AC代码2(使用数组)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
void to_array(int num,int a[])
{
for(int i=0;i<4;i++)
{
a[3-i]=num%10;
num/=10;
}
}
int to_number(int a[])
{
int now=1;
int num=0;
for(int i=0;i<4;i++)
{
num+=now*a[3-i];
now*=10;
}
return num;
}
int compare1(const void*a,const void*b)
{//从小到大排序
int *pa=(int *)a;
int *pb=(int *)b;
return (*pa)>(*pb)?1:-1;
}
int compare2(const void*a,const void*b)
{//从小到大排序
int *pa=(int *)a;
int *pb=(int *)b;
return (*pb)>(*pa)?1:-1;
}
int main()
{
//freopen("input.txt","r",stdin);//用于读入input.txt中的数据
int num;
scanf("%d",&num);
int array[4];
int a,b,c;
while(1)
{
to_array(num,array);
qsort(array,4,4,compare2);
a=to_number(array);
qsort(array,4,4,compare1);
b=to_number(array);
c=a-b;
printf("%04d - %04d = %04d",a,b,c);//4表示位宽,不足4位在前面补0,大于等于4位不做操作
if(c==0||c==6174)break;
else printf("\n");
num=c;
}
}
小知识
itoa函数:属于stdlib.h头文件
char *itoa( int value, char *string,int radix); [1]
原型说明:
value:欲转换的数据。
string:目标字符串的地址。
radix:转换后的进制数,可以是10进制、16进制等。
示例如下
atoi函数:由字符串转换为整数型