PTA 特立独行的幸福 java

对一个十进制数的各位数字做一次平方和,称作一次迭代。如果一个十进制数能通过若干次迭代得到 1,就称该数为幸福数。1 是一个幸福数。此外,例如 19 经过 1 次迭代得到 82,2 次迭代后得到 68,3 次迭代后得到 100,最后得到 1。则 19 就是幸福数。显然,在一个幸福数迭代到 1 的过程中经过的数字都是幸福数,它们的幸福是依附于初始数字的。例如 82、68、100 的幸福是依附于 19 的。而一个特立独行的幸福数,是在一个有限的区间内不依附于任何其它数字的;其独立性就是依附于它的的幸福数的个数。如果这个数还是个素数,则其独立性加倍。例如 19 在区间[1, 100] 内就是一个特立独行的幸福数,其独立性为 2×4=8。

另一方面,如果一个大于1的数字经过数次迭代后进入了死循环,那这个数就不幸福。例如 29 迭代得到 85、89、145、42、20、4、16、37、58、89、…… 可见 89 到 58 形成了死循环,所以 29 就不幸福。

本题就要求你编写程序,列出给定区间内的所有特立独行的幸福数和它的独立性。

输入格式:
输入在第一行给出闭区间的两个端点:1<A<B≤10
​4
​​ 。

输出格式:
按递增顺序列出给定闭区间 [A,B] 内的所有特立独行的幸福数和它的独立性。每对数字占一行,数字间以 1 个空格分隔。

如果区间内没有幸福数,则在一行中输出 SAD。

输入样例 1:
10 40

输出样例 1:
19 8
23 6
28 3
31 4
32 3

注意:样例中,10、13 也都是幸福数,但它们分别依附于其他数字(如 23、31 等等),所以不输出。其它数字虽然其实也依附于其它幸福数,但因为那些数字不在给定区间 [10, 40] 内,所以它们在给定区间内是特立独行的幸福数。

输入样例 2:
110 120

输出样例 2:
SAD

建立2个数组,一个数组标记未处理处理过(0)、不幸福数(1)、不幸福的数字(2)、特立独行的幸福数(3),另外一个数组标记依赖数字的数量。
这里我将2个数组合到一起,用的是一个两列的二维数组,标记依赖数量和数字的类型的方式是用的回溯
废话不多说,注释都有
题目传送门:https://pintia.cn/problem-sets/994805046380707840/problems/1111914599412858886

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.StringTokenizer;

public class Main {
	public static void main(String[] args) throws IOException {
		Reader.init(System.in);
		a = Reader.nextInt();
		b = Reader.nextInt();
		luck = new int[10001][2];
		// 对每个数字进行判断
		for (int i = a; i <= b; i++) {
			// 判断是否处理过,没有处理过的是0
			if (luck[i][0] == 0) {
				// 记录下位置当前处理的数字
				index = i;
				// 判断是否是幸福数 若是 则这个数字是特立独行的幸福数
				if(fun(i) == 2) {
					luck[i][0] = 3;
				}
			}
		}
		
		// 输出结果
		boolean have = false;
		for (int i = a; i <= b; i++) {
			// 若是是特立独行的幸福数,则进行素数判断并输出
			if (luck[i][0] == 3) {
				have = true;
				if (isPrime(i)) {
					System.out.println(i + " " + (2 * luck[i][1]));
				} else {
					System.out.println(i + " " + luck[i][1]);
				}
			}
		}
		
		if (!have) {
			System.out.println("SAD");
		}
	}
	
	// 区间
	static int a, b;
	// 第一位用来标记当前数字是否幸福数,其中一表示是不幸福数,二表示是幸福数,三表示幸福数
	// 第二位用来记录依赖数
	static int[][] luck; 
	static int index;
	static int count;
	
	
	static int fun(int val) {
		// 判断当前数字是不是幸福数
		if (val == 1 || luck[val][0] == 2 || luck[val][0] == 3) {
			// 记录层数,回溯时给每个幸福数确定依赖数字
			luck[index][1] = luck[val][1];
//			System.out.println("============luck============");
			return luck[val][0] = 2;
		}
		
		// 判断当前数字是不是不幸福数字,由于幸福数字已经判断过了,则只要当前数字是被处理过的,则一定是不幸福的数字
		if (luck[val][0] != 0) {
//			System.out.println("------------unluck------------");
			return 1;
		}
		
		// 计算平方和,结果放入sum
		int sum = 0;
		int current = val;
		int factor = 0;
		while (current != 0) {
			factor = current % 10;
			sum += factor * factor;
			current /= 10;
		}
		
//		System.out.println(val + "->"+sum);
		// 先标记已经处理过,默认标记为不幸福数字
		luck[val][0] = 1;
		// 判断当前数字是幸福数字还是不幸福数字,二表示幸福数字,一表示不幸福数字
		luck[val][0] = fun(sum);
		// 回溯给出依赖数量
		luck[val][1] = ++luck[index][1];
		
		return luck[val][0];
	}

	public static boolean isPrime(int m) {
		if (m == 1) {
			return false;
		}
		// 2 、 3 单独处理
		if (m == 2 || m == 3) {
			return true;
		}
		// 不在6的倍数两边的一定不是素数
		if (m % 6 != 1 && m % 6 != 5) {
			return false;
		}
		int sqrt_m = (int) Math.sqrt(m);
		// 在6的倍数两侧的也可能不是素数
		for (int i = 5; i <= sqrt_m; i += 6) {
			if (m % i == 0 || m % (i + 2) == 0) {
				return false;
			}
		}
		// 排除所有 剩下就是素数了
		return true;
	}
}

// Class for buffered reading int and double values *//*
class Reader {
	static BufferedReader reader;
	static StringTokenizer tokenizer;

	// ** call this method to initialize reader for InputStream *//*
	static void init(InputStream input) {
		reader = new BufferedReader(new InputStreamReader(input));
		tokenizer = new StringTokenizer("");
	}

	static void init(File file) {
		try {
			reader = new BufferedReader(new FileReader(file));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		tokenizer = new StringTokenizer("");
	}

	// ** get next word *//*
	static String next() throws IOException {
		while (!tokenizer.hasMoreTokens()) {
			// TODO add check for eof if necessary
			tokenizer = new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}

	static String nextLine() throws IOException {
		return reader.readLine();
	}

	static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	static char nextChar() throws IOException {
		return next().toCharArray()[0];
	}

	static float nextFloat() throws IOException {
		return Float.parseFloat(next());
	}

	static Double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}
}

7-6 特立独行幸福 (25分) 对一个十进制数的各位数字做一次平方和,称作一次迭代。如果一个十进制数能通过若干次迭代得到 1,就称该数为幸福数。1 是一个幸福数。此外,例如 19 经过 1 次迭代得到 82,2 次迭代后得到 68,3 次迭代后得到 100,最后得到 1。则 19 就是幸福数。显然,在一个幸福数迭代到 1 的过程中经过的数字都是幸福数,它们的幸福是依附于初始数字的。例如 82、68、100 的幸福是依附于 19 的。而一个特立独行幸福数,是在一个有限的区间内不依附于任何其它数字的;其独立性就是依附于它的的幸福数的个数。如果这个数还是个素数,则其独立性加倍。例如 19 在区间[1, 100] 内就是一个特立独行幸福数,其独立性为 2×4=8。 另一方面,如果一个大于1的数字经过数次迭代后进入了死循环,那这个数就不幸福。例如 29 迭代得到 85、89、145、42、20、4、16、37、58、89、…… 可见 89 到 58 形成了死循环,所以 29 就不幸福。 本题就要求你编写程序,列出给定区间内的所有特立独行幸福数和它的独立性。 输入格式: 输入在第一行给出闭区间的两个端点:1<A<B≤10 ​4 ​​ 。 输出格式: 按递增顺序列出给定闭区间 [A,B] 内的所有特立独行幸福数和它的独立性。每对数字占一行,数字间以 1 个空格分隔。 如果区间内没有幸福数,则在一行中输出 SAD。 输入样例 1: 10 40 输出样例 1: 19 8 23 6 28 3 31 4 32 3 注意:样例中,10、13 也都是幸福数,但它们分别依附于其他数字(如 23、31 等等),所以不输出。其它数字虽然其实也依附于其它幸福数,但因为那些数字不在给定区间 [10, 40] 内,所以它们在给定区间内是特立独行幸福数。 输入样例 2: 110 120 输出样例 2: SAD
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值