首页 > 学院 > 开发设计 > 正文

5位数字黑洞

2019-11-06 06:52:08
字体:
来源:转载
供稿:网友

1007.5位数字黑洞

Description

任意一个5位数,比如:34256,把它的各位数字打乱,重新排列,可以得到一个最大的数:65432,一个最小的数23456。求这两个数字的差,得:41976,把这个数字再次重复上述过程(如果不足5位,则前边补0)。如此往复,数字会落入某个循环圈(称为数字黑洞)。比如,刚才的数字会落入:[82962, 75933, 63954, 61974] 这个循环圈。请编写程序,找到5位数所有可能的循环圈,并输出,每个循环圈占1行。其中5位数全都相同则循环圈为 [0],这个可以不考虑。循环圈的输出格式仿照:[82962, 75933, 63954, 61974]其中数字的先后顺序可以不考虑。

Input

Output

[74943, 62964, 71973, 83952][63954, 61974, 82962, 75933][53955, 59994][0]模拟上述过程即可,注意优化
import java.util.Arrays;public class T71 {		static int[] data=new int[10000*10+1];			public static void main(String[] args) {		for (int i = 10000; i <= 100000; i++) {						if (convert(i) == 0) { //对于 XXXXX这样的数(例如33333),不用处理。				data[i] = 1;    //标记出现过num				continue;			}			if (data[i] == 1){  //已出现过的数不再处理。				continue;			}			getQuan(i);		}	}	PRivate static void getQuan(int k) {		int[] arr=new int[1000];		arr[0]=k;				//主要的不同点:将每次做差得到的数依次放进数组中,然后输出圈的时候比较方便		//老师的将得到的数做数组下标,放进圈中,然后打印圈什么的有点复杂		while(data[k]!=1){						data[k]=1;			int m=convert(k);			k=m;			for (int i = 1; i < arr.length; i++) {				if(arr[i]==0){//圈中没有的数,放进圈中					arr[i]=m;					break;				}else{					if(arr[i]==m){//找到了圈,打印						System.out.print("[");						for (int j = i; j < arr.length; j++) {							if(arr[j]==0){								System.out.println("]");								return;							}							System.out.print(arr[j]);							if(arr[j+1]!=0)								System.out.print(",");						}					}				}			}		}	}	private static int convert(int n) {		int[] arr = new int[5];		for (int i = 0; i < 5; i++) {			arr[i] = n % 10;			n /= 10;		}		Arrays.sort(arr);		int max = 0;		int min = 0;		int tenN = 1;		for (int i = 0; i < 5; i++) {			min = 10 * min + arr[i];			max += tenN * arr[i];			tenN *= 10;		}				return max - min;	}}老师写的方法:
import java.util.Arrays;import java.util.LinkedList;import java.util.Queue;public class T7 {static int[] visited = new int[100000]; // 放所有出现过的数static int[] now = new int[100000];  	//存放当前数变换出的所有结果//双击查看原图到并打印第一次出现的圈private static void printCircle(int num) {	int k = num;		while (visited[k] != 1  && now[k] != 1 )  //如果没有遇到圈(原来没有出现,且本轮也没有出现),则继续变换	{now[k] = num;	 //(1)标记本轮(num起点)出现过n	visited[k] = 1; 	 //(2)标记出现过n	k = convert(k);	 //(3)继续变换	}  	if(now[k]==num){	//本轮新出现的圈		Queue<Integer>  queue = new LinkedList<Integer>(); //放环中的元素	queue.add(k);	 //k入队	k = convert(k);	while (k != queue.peek()) {	queue.add(k);  	k = convert(k); }System.out.print( "[");while( queue.size()>1) {System.out.print( queue.poll() + ",");}System.out.println(queue.poll()+"]");}}/**  * @param n * @return 返回n变换后的值。 * 即各位数字打乱,重新排列,得到的最大数-最小数 */private static int convert(int n) {int[] arr = new int[5];for (int i = 0; i < 5; i++) {arr[i] = n % 10;n /= 10;}Arrays.sort(arr);int max = 0;int min = 0;int tenN = 1;for (int i = 0; i < 5; i++) {min = 10 * min + arr[i];max += tenN * arr[i];tenN *= 10;}	return max - min;}public static void main(String[] args) {for (int num = 10000; num < 100000; num++) {	//穷举五位数	if (convert(num) == 0) { //对于 XXXXX这样的数(例如33333),不用处理。visited[num] = 1;    //标记出现过numcontinue;}if (visited[num] == 1)  //已出现过的数不再处理。continue;printCircle(num);	 //输出圈(只输出第一次出现的情况)}}}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表