蓝桥杯基础 数论 黑洞数

黑洞数是指于四位数中,只要数字不完全相同,将数字由大到小的排列减去由小到大的排列。假设一开始选定的数字为 =f( ), =f( ),..., =f( ) 用同样的规则继续算下去,最后的结果一定是 6174 。 比如说一开始选定9891,则f(9891)=9981-1899=8082,f(8820)=8820-0288=8532,f(8532)=8532-2358=6174,f(7641)=7641-1467=6174~

其他的四位数经过这样一系列的运算后,在七步之内都会对应到6174。这种现象类似黑洞(进去后就出不来了),故称为黑洞数。


除此以外,三位数也有一个类似的黑洞数495

5位数的状况:没有黑洞,有3个循环

71973 83952 74943 62964 71973
82962 75933 63954 61974 82962
53955 59994 53955

6位数的状况:有2个黑洞631764、549945,还有1个7个成员的循环

420876 851742 750843 840852 860832 862632 642654 420876

7位数的状况:没有黑洞,只有1个8成员的循环

7509843 9529641 8719722 8649432 7519743 8429652 7619733 8439522 7509843

8位数的状况:有2个黑洞63317664、97508421

9位数的状况:有2个黑洞554999445、864197532

10位数的状况:有3个黑洞6333176664、9753086421、9975084201

以上转自维基百科: https://zh.wikipedia.org/wiki/%E9%BB%91%E6%B4%9E%E6%95%B8


5位黑洞数题目:
五位黑洞数 
任意一个5位数,比如:34256,把它的各位数字打乱,重新排列,可以得到一个最大的数:65432,一个最小的数23456。
求这两个数字的差,得:41976,把这个数字再次重复上述过程(如果不足5位,则前边补0)。
如此往复,数字会落入某个循环圈(称为数字黑洞)。
比如,刚才的数字会落入:82962 75933 63954 61974 这个循环圈。


请编写程序,找到5位数所有可能的循环圈,并输出,每个循环圈占1行。其中5位数全都相同则循环圈为 0,这个可以不考虑。


循环圈的输出格式仿照:
82962 75933 63954 61974

其中数字的先后顺序可以不考虑。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int MAX = 100010;
int vis[MAX], map[MAX];  //map表示该循环输出过 
queue <int> q;
void search(int n) {
	int maxn, minn;
	char num[10];
	while(1) {
		sprintf(num, "%5d", n);
		sort(num, num + 5);
		sscanf(num, "%d", &minn);
		strcpy(num, strrev(num));  //逆转求出最大值 
		sscanf(num, "%d", &maxn);
		n = maxn - minn;
		if(map[n]) break;  //以前输出过该循环,退出。 
		if(vis[n]) {  //出现循环 
			while(q.front() != n) {  //将循环之前的数排除 
				q.pop();
			}
			while(!q.empty()) {
				printf("%d ", q.front());
				map[q.front()] = 1;  //标记已经输出 
				q.pop();
			}
			printf("\n");
		}
		else {
			vis[n] = 1;
			q.push(n);
		}
	}
}
int main() {
	int i, j;
	for(i = 10000; i < 100000; i++) {
		memset(vis, 0, sizeof(vis));  //每个数都要初始化一次 
		if(i % 10 == i / 10 % 10 && i % 10 == i / 100 % 10 && i % 10 == i / 1000 % 10 && i % 10 == i / 10000) {
			continue;
		}
		while(!q.empty()) {  //每个数都要清空一次队列 
			q.pop();
		}
		q.push(i);
		vis[i] = 1;
		search(i);
	}
	return 0;
}

练习题目:nyoj-57  http://acm.nyist.net/JudgeOnline/problem.php?pid=57

6174问题

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 2
描述

假设你有一个各位数字互不相同的四位数,把所有的数字从大到小排序后得到a,从小到大后得到b,然后用a-b替换原来这个数,并且继续操作。例如,从1234出发,依次可以得到4321-1234=3087、8730-378=8352、8532-2358=6174,又回到了它自己!现在要你写一个程序来判断一个四位数经过多少次这样的操作能出现循环,并且求出操作的次数

比如输入1234执行顺序是1234->3087->8352->6174->6174,输出是4

输入
第一行输入n,代表有n组测试数据。
接下来n行每行都写一个各位数字互不相同的四位数
输出
经过多少次上面描述的操作才能出现循环
样例输入
1
1234
样例输出
4


简单题,模拟过。

 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
bool cmp(char a, char b) {
	return a > b;
}
int main() {
	int n;
	scanf("%d", &n);
	while(n--) {
		int num;
		scanf("%d", &num);
		int t = num;
		int cnt = 0;
		do{
			char s[10];
			sprintf(s, "%4d", num);
			sort(s, s + 4);
			int minn, maxn;
			sscanf(s, "%d", &minn);
			sort(s, s + 4, cmp);
			sscanf(s, "%d", &maxn);
			t = num;
			num = maxn - minn;
			cnt++;
		}while(t != num);
		printf("%d\n", cnt);
	}
	return 0;
}        


你可能感兴趣的:(蓝桥杯基础 数论 黑洞数)