求解黑洞数

问题描述:

黑洞数又称陷阱数,是类具有奇特转换特性的整数。任何一个数字不全相同的整数,
经有限“重排求差”操作,总会得到某一个或一些数,这些数即为黑洞数。
“重排求差”操作即把组成该数的数字重排后得到的最大数减去重排后得到的最小数。
举个例子,3位数的黑洞数为495.

简易推导过程:随便找个数,如297,3个位上的数从小到大和从大到小各排一次,
为972和279,相减得693。按上面做法再做一次,得到594,再做一次,得到495,
之后反复都得到495。

验证4位数的黑洞数为6174。

解题思路:

#include<stdio.h>
#include<iostream>
#include<stdlib.h>
using namespace std;
#define LENTH 100
/* 降序:冒泡排序 */
void dec_sort(int array[],int n)
{
	int flag = 0;
	for(int i=0;i<n-1;++i)//n-1趟排序
	{
		for(int j=0;j<n-i-1;++j)//第i趟比较n-i次,因为i从0开始,所以还得-1
		{
			if(array[j] < array[j+1])
			{
				array[j]  += array[j+1];//array[j] = array[j] + array[j+1]
				array[j+1] = array[j] - array[j+1];
				array[j]  -= array[j+1];//array[j] = array[j] - array[j+1]
				flag = 1;
			}
		}
		if(flag == 0)//在一趟排序中若未发生交换,表明已经排序好,退出程序
			break;
	}
}
/* 升序:选择排序 */
void inc_sort(int array[],int n)
{
	int k;
	for(int i=0;i<n-1;++i)//n个数,将前n-1个数放置好就结束了
	{
		k = i;//假设要排序的一组数据中第一个数最小(k存放待排序数据中最小值的下标)
		for(int j=k+1;j<n;++j)
		{
			if(array[j] < array[k])//若存在比当前值还小的数,则交换下标
			{
				k = j;
			}
		}
		if(k != i)
		{
			array[i] += array[k];
			array[k]  = array[i] - array[k];
			array[i] -= array[k];
		}
	}
}
int black_hole_num(int n)
{
	cout<<n<<endl;
	//注意:!!!求解过程中会改变n的值,而下面要用到n,不想它改变
	//所以用临时变量保存他的值,改变临时变量,而不改变它
	int temp = n;
	int array[LENTH];
	int i = 0;
	int count;
	int max = 0;
	int min = 0;
/* 将该数值的各个位存放在数组中 */
	while(temp)
	{
		array[i] = temp%10;
		i++;
		temp /= 10;
	}
	count = i;
/* 元素升序之后,求解最小值*/
	inc_sort(array,count);
	for(i=0;i<count;++i)
	{
		min = min*10 + array[i];
	}
/* 元素降序之后,求解最大值*/
	dec_sort(array,count);
	for(i=0;i<count;++i)
	{
		max = max*10 + array[i];
	}

/*	if(max - min == n)//此处要用到n的值,所以改变临时变量而不改变n
		return n;
	else
		return black_hole_num(max - min);*/
	return (max - min == n) ? n:black_hole_num(max - min);
}
int main()
{
	int flag = 1;
	int n;
	int num;
	system("mode con cols=100 lines=100");
	system("color 0A");
	while(flag)
	{
		cout<<"----------求解黑洞数-------------"<<endl;
		cout<<"                        zyh_helen"<<endl;
		cout<<"请输入您要求的黑洞数的位数:"<<endl;
		cin>>n;
		cout<<"请输入"<<n<<"个:任何一个数字不全相同的整数"<<endl;
		cin>>num;
		cout<<"黑洞数为:"<<black_hole_num(num)<<endl;
		cout<<"continue:1  break:0"<<endl;
		cin>>flag;
	}
	return 0;
}

当输入5的时候,会陷入[82962,75933,63954,61974]循环圈中

<span style="color:#ff0000;">任何一个数字不全相同的整数,
经有限“重排求差”操作,总会得到某一个或</span><span style="color:#3333ff;">一些数</span><span style="color:#ff0000;">,这些数即为黑洞数。</span>
时间: 2024-10-25 15:14:51

求解黑洞数的相关文章

hdu 4651 Partition (利用五边形定理求解切割数)

下面内容摘自维基百科: 五边形数定理[编辑] 五边形数定理是一个由欧拉发现的数学定理,描写叙述欧拉函数展开式的特性[1] [2].欧拉函数的展开式例如以下: 亦即 欧拉函数展开后,有些次方项被消去,仅仅留下次方项为1, 2, 5, 7, 12, ...的项次,留下来的次方恰为广义五边形数. 当中符号为- - + + - - + + ..... 若将上式视为幂级数,其收敛半径为1,只是若仅仅是当作形式幂级数(formal power series)来考虑,就不会考虑其收敛半径. 和切割函数的关系

hdu 4651 Partition (利用五边形定理求解分割数)

以下内容摘自维基百科: 五边形数定理[编辑] 五边形数定理是一个由欧拉发现的数学定理,描述欧拉函数展开式的特性[1] [2].欧拉函数的展开式如下: 亦即 欧拉函数展开后,有些次方项被消去,只留下次方项为1, 2, 5, 7, 12, ...的项次,留下来的次方恰为广义五边形数. 其中符号为- - + + - - + + ..... 若将上式视为幂级数,其收敛半径为1,不过若只是当作形式幂级数(formal power series)来考虑,就不会考虑其收敛半径. 和分割函数的关系 欧拉函数的倒

求解Catalan数,(大数相乘,大数相除,大数相加)

Catalan数 卡塔兰数是组合数学中一个常在各种计数问题中出现的数列.以比利时的数学家欧仁·查理·卡塔兰(1814–1894)命名.历史上,清代数学家明安图(1692年-1763年)在其<割圜密率捷法>最早用到"卡塔兰数",远远早于卡塔兰.有中国学者建议将此数命名为"明安图数"或"明安图-卡塔兰数".卡塔兰数的一般公式为 C(2n,n)/(n+1). 性质: 令h(0)=1,h(1)=1,卡塔兰数满足递归式: h(n)= h(0)*

编译器? 求解两数运算?

这个问题也不算新鲜了,换一种方式提问就是"如何不用 + - * / 运算符,来求解两元素之和"的问题:大家很自然的回想起利用位运算.在数字电路中,我们都遇到过设计"加法器"的问题,利用位与.或.非.异或可以很轻松的解决此问题:这里,不用此方式,而是借助编译器的地址偏移,来解决问题.基本思路如下:(1)将其中int型数据转为地址(或者说是一个数组的首地址)(2)然后利用数组下角标索引,进行地址偏移,获取偏移后的address (3)将(2)中得到的地址转换为int类型

【编程小题目8】求解完数

题目:一个数如果恰好等于它的因子之和,这个数就称为"完数".例如6=1+2+3.编程 找出100以内的所有完数. 分析:本质还是求质因数. #include <iostream> using namespace std; bool IsPerfect(int n){ int i, j = 0; int Temp = n,Sum = 1; int arr[100] = {'0'}; for(i = 2; i <= n; i++) { if(i == n) { arr[j

python_黑洞数

>>> def main(n): start = 10**(n-1)+2 end = start*10-20 for i in range(start,end): i = str(i) big = ''.join(sorted(i,reverse=True)) big = int(big) little = ''.join(sorted(i)) little = int(little) if big-little==int(i): print(i) >>> n=4>

DAY 004--递归求某数的阶乘

004-- 用递归求解某数的阶乘 n的阶乘:n(n-1)(n-2)(n-3)****1 流程分析:                                                                             1.输入某个数字n,计算该数字的阶乘:n! 2.递归求阶乘函数,参数为n: 2.1.判断数字是否等于1,如果等于1 ,函数返回1 2.2.如果函数不返回1,则函数返回n*fun(n-1),以此递归 代码分析:                   

poj2284 That Nice Euler Circuit(欧拉公式)

题目链接:poj2284 That Nice Euler Circuit 欧拉公式:如果G是一个阶为n,边数为m且含有r个区域的连通平面图,则有恒等式:n-m+r=2. 欧拉公式的推广: 对于具有k(k≥2)个连通分支的平面图G,有:n-m+r=k+1. 题意:给出连通平面图的各顶点,求这个欧拉回路将平面分成多少区域. 题解:根据平面图的欧拉定理“n-m+r=2”来求解区域数r. 顶点个数n:两两线段求交点,每个交点都是图中的顶点. 边数m:在求交点时判断每个交点落在第几条边上,如果一个交点落在

HDU 5119 Happy Matt Friends(DP)

求解方案数的简单DP,比赛时没有往DP上想,思维比较局限. 状态转移很好写,类似于背包,我用记忆化搜索写的容易写,但是效率比较低,还占内存,读者可以改成递推式,还可以改成滚动数组,因为每一层的状态只用到它上一层的状态 . 细节参见代码: #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #include<map