1019 数字黑洞 (20 分)

题面:

给定任一个各位数字不完全相同的 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

思路一:

  1. 创建一个数组,直接输入数组
  2. 数组作为排序和输出作用
  3. 计算转换为int计算
#include <iostream>
#include <algorithm>
#include <math.h>
using namespace std;

bool cmp1(int a,int b){
    return a>b;
}

bool cmp2(int a,int b){
    return a<b;
}

void print(int x[]){
    for(int i=0;i<4;i++){
        cout << x[i];
    }
}

//数组变为int
int change(int x[]){
    int sum=0;
    for (int i=0;i<4;i++){
        sum += x[i] * pow(10,3-i);
    }
    return sum;
}

int count(int x[]){
    int a,b;
    sort(x,x+4,cmp1);
    print(x);
    a = change(x);

    cout << " - ";

    sort(x,x+4,cmp2);
    print(x);
    b = change(x);

    cout << " = ";

    return a-b;
}

int main(){
    char number[4];
    cin >> number;
    int suan[4];
    for (int i=0;i<4;i++){
        suan[i] = number[i] - '0';
    }

    while(1){
        int x = count(suan);
        int a = x;
        for (int i=3;i>=0;i--){
            suan[i] = a%10;
            a = a / 10;
        }
        print(suan);
        cout << endl;

        if(x==0 || x==6174){
            break;
        }

    }

    return 0;
}

结果
样例通过,但是由答案错误出现。
但是我反复推敲,一看再看,试了很多数据,没有错,于是上网看了看别人的答案

思路二

  1. 用int输入,其余不变
#include <iostream>
#include <algorithm>
#include <math.h>
using namespace std;

bool cmp1(int a,int b){
    return a>b;
}

bool cmp2(int a,int b){
    return a<b;
}

void print(int x[]){
    for(int i=0;i<4;i++){
        cout << x[i];
    }
}

//数组变为int
int change(int x[]){
    int sum=0;
    for (int i=0;i<4;i++){
        sum += x[i] * pow(10,3-i);
    }
    return sum;
}

int count(int x[]){
    int a,b;
    sort(x,x+4,cmp1);
    print(x);
    a = change(x);

    cout << " - ";

    sort(x,x+4,cmp2);
    print(x);
    b = change(x);

    cout << " = ";

    return a-b;
}

int main(){
    int y;
    cin >> y;
    int suan[4];

    for (int i=3;i>=0;i--){
        suan[i] = y%10;
        y = y / 10;
    }

    while(1){
        int x = count(suan);
        int a = x;
        for (int i=3;i>=0;i--){
            suan[i] = a%10;
            a = a / 10;
        }
        print(suan);
        cout << endl;

        if(x==0 || x==6174){
            break;
        }

    }

    return 0;
}

结果
AC

反思

发现了一个第一种思路不能解决的问题,要是输入的数字不是四位数的话,就没有办法得到正常的结果。

于是尝试将一开始的char[ ]进行初始化,用的是memset( )函数,将数组先初始化为’0’,但是还是不行,输入三位数最后一个数字也还不能是0,一直是-48。

考虑到可能是cin输入方式的问题 ,采用scanf("%s",numebr)的方式输入,也是一样的问题。

然后去查了一下char为什么会输出负数,
在这里插入图片描述
怀着我没有错的想法,开始改第一种思路:

为什么初始化没有用,想到了可能输入数组的时候系统取了回车键,然后把回车键过滤掉试试,打印也直接打印字符

然后过了,世界真奇妙,条条大路通罗马

#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
using namespace std;

bool cmp1(char a,char b){
    return a>b;
}

bool cmp2(char a,char b){
    return a<b;
}

void print(char x[]){
    for(int i=0;i<4;i++){
        cout << x[i];
    }
}

//数组变为int
int change(char x[]){
    int sum=0;
    for (int i=0;i<4;i++){
        sum += (x[i]-'0') * pow(10,3-i);
    }
    return sum;
}

int count(char x[]){
    int a,b;
    sort(x,x+4,cmp1);
    print(x);
    a = change(x);

    cout << " - ";

    sort(x,x+4,cmp2);
    print(x);
    b = change(x);

    cout << " = ";

    return a-b;
}

int main(){
    char suan[4];
    memset(suan,'0', sizeof(suan));
//    print(suan);
//    cout << endl;
//    string h;
//    cin>>h;
    for(int i=0;i<4;i++){
    	char x;
    	x = cin.get();
    	if(x=='\n'){
    		break;
    	}
    	suan[i] = x;
    }

    while(1){
        int x = count(suan);
        int a = x;
        for (int i=3;i>=0;i--){
            suan[i] = (a%10)+'0';
            a = a / 10;
        }
        print(suan);
        cout << endl;

        if(x==0 || x==6174){
            break;
        }

    }

    return 0;
}

最大的失误其实还是没有审题审清楚,我一开始以为题目只会输入四位数,但是后面发现是一个范围的数值,没有审清楚题目。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值