【PTA刷题整理】PAT 乙级 1019 数字黑洞

2020.03.08 今天是三八妇女节喔


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


法一

看到了要对每个数进行排序就很自然的想到了sort()函数,又因为要递增递减各一次,就用了vector()容器(这里要注意的是不能直接用vector + 下标 = 值的形式进行赋值,要利用数组进行初始化),可以使用rbegin() , rend(),其实直接写一个数组然后写一个递减的比较法则放入sort()函数里面也是一样的,使用pow()函数a += temp[i] * pow(10 , temp.size() - i - 1);将每一位还原为一个四位数,可以好好利用这个i,最后就是最烦人的一步,不足四位数的也要按四位输出,可以循环模1000输出每一位数
注意:
1、当N - N = 0时结束循环,循环结束条件要加上差为0
2、个人感觉必定有一组数据,**一开始直接给的就是6174,所以需要对6174进行标记,**当第一次进入时为true,进入后则将标记改为false

#include<iostream>                  //输入输出流头文件
#include<stdio.h>                   //标准输入输出
#include<stdlib.h>
#include<math.h>                    //数学函数
#include<string.h>                  //C语言字符数组的字符串
#include<algorithm>                 //C++标准模板库的函数
#include<map>                       //map映射容器
#include<unordered_map>             //无序的map映射容器
#include<vector>                    //变长数组容器
#include<queue>                     //队列
#include<stack>                     //栈
#include<string>                    //C++string类
#include<set>                       //set集合
#define SIZE 4
using namespace std;                //标准命名空间

                                    //可以加入全局变量或者其他函数

void Output(int m){
    int temp = 1000;
    for(int i = 0; i < 4; i++){
        cout << (m / temp);
        m %= temp;
        temp /=10;
    }
}

int main(){                         //主函数
#ifdef ONLINE_JUDGE                 //如果有oj系统(在线判定),则忽略文件读入,否则使用文件作为标准输入
#else
    freopen("1.txt", "r", stdin);   //从1.txt输入数据
#endif
	int ans , num[4];
	cin >> ans;
//	cout << ans << endl;
	
	bool index = true;
	while(ans != 0 && (ans != 6174 || index)){
		index = false;
		for(int i = 0; i < 4; i++){
            num[i] = ans % 10;
            ans /= 10;
        }
        vector<int> temp(num ,num + 4);
		int a  = 0, b = 0;
		sort(temp.rbegin() , temp.rend());
		for(int i = 0 ; i < temp.size() ; i++){
			a += temp[i] * pow(10 , temp.size() - i - 1);
		}
		//cout <<a << endl;
		sort(temp.begin() , temp.end());
		for(int j = 0 ; j < temp.size() ; j++){
			b += temp[j] * pow(10 , temp.size() - j - 1);
		}
		//cout << b << endl;
		ans = a - b;
		Output(a);
		cout << " - "; 
		Output(b);
		cout << " = ";
		Output(ans);
		cout << endl;
	}
    return 0;                       
}


法二

第二种方法是在网上看到的,感觉会比较容易理解

#include<stdio.h>
#include<stdlib.h>

int comp(const void*a, const void*b)
{
  return *(int*)b - *(int*)a;
}

int main()
{
  int num[4];
  int max, min, n;
  scanf("%d",&n);
    //分离数字
    num[0] = n / 1000;
    num[1] = n / 100 % 10;
    num[2] = n / 10 % 10;
    num[3] = n % 10;

  int temp;
  while (1)
  {
    qsort(num, 4, sizeof(int), comp);		//排序
    max = 1000 * num[0] + 100 * num[1] + 10 * num[2] + num[3];
    min = 1000 * num[3] + 100 * num[2] + 10 * num[1] + num[0];

    temp = max - min;
    if (max == min)
    {
      printf("%04d - %04d = 0000", max, max);
      return 0;
    }
    else
    {
      printf("%04d - %04d = %04d\n", max, min, temp);
      if (6174 == temp)
      {
        return 0;
      }

      num[0] = (temp / 1000);
      num[1] = temp / 100 % 10;
      num[2] = temp / 10 % 10;
      num[3] = (temp % 10);
    }

  }
  return 0;
}
发布了22 篇原创文章 · 获赞 2 · 访问量 495

猜你喜欢

转载自blog.csdn.net/weixin_43849089/article/details/104734958