L1-006 连续因子
连续因子探测算法
- 遍历起点:从2到√n尝试每个数字作为连续因子链起点
- 计算链长:对每个起点,通过连续除法检测能分解n的最大连续数字链
- 质数特判:若无连续因子链(res=0),说明n是质数,直接输出自身
- 格式化输出:最长链长 + 用"*"连接的因子序列
import java.io.*;
import java.util.*;
public class Main {
static BufferedReader sc = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
static String[] ss;
static String s;
public static void main(String[] args) throws IOException {
pre();
int T = 1;
while (T-- > 0) solve();
sc.close();
out.flush();
out.close();
}
private static void pre() throws IOException {}
static long MOD = 1000000007;
public static void solve() throws IOException {
int n = Integer.parseInt(sc.readLine());
int res = 0; // 最长连续因子链长度
int l = 1; // 最长链的起始数字
// 遍历所有可能的连续因子起点(2到√n)
for (int i = 2; i <= Math.sqrt(n); i++) {
int temp = n; // 当前待分解数
int cnt = 0; // 当前连续因子计数
// 检查连续因子链:i, i+1, i+2...
for (int j = i; temp != 0 && temp % j == 0; j++) {
temp /= j; // 分解数字
cnt++; // 链长增加
}
// 更新最长记录
if (cnt > res) {
res = cnt;
l = i; // 记录新起点
}
}
// 处理质数情况(最长链长为1的特殊输出)
if (res == 0) {
out.println("1");
out.print(n);
}
// 正常情况输出(格式:长度+因子链)
else {
out.println(res);
StringBuilder sb = new StringBuilder().append(l);
for (int i = l+1; i < l+res; i++) sb.append("*").append(i);
out.print(sb);
}
}
}
L1-007 念数字
映射表直接转换法
- 预定义字典:用HashMap存储字符到拼音的映射(包含负号)
- 分段输出:前n-1个字符输出"拼音+空格",最后一个单独输出避免末尾空格
- 时间复杂度:O(n)线性遍历,每个字符只需一次哈希表查询
(关键技巧:通过分开处理最后一位解决格式化输出难题)
import java.io.*;
import java.util.*;
public class Main {
static BufferedReader sc = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
static String[] ss;
static String s;
public static void main(String[] args) throws IOException {
String num = sc.readLine(); // 读取输入数字字符串
// 创建数字到拼音的映射表(含负号处理)
Map<Character, String> res = new HashMap<>();
res.put('-', "fu");
res.put('0', "ling");
res.put('1', "yi");
res.put('2', "er");
res.put('3', "san");
res.put('4', "si");
res.put('5', "wu");
res.put('6', "liu");
res.put('7', "qi");
res.put('8', "ba");
res.put('9', "jiu");
int len = num.length();
// 遍历处理前n-1个字符:输出拼音+空格
for(int i=0;i<len-1;i++) {
char c = num.charAt(i);
if(res.containsKey(c)) {
out.print(res.get(c)+" ");
}
}
// 单独处理最后一个字符:避免末尾多余空格
out.println(res.get(num.charAt(len-1)));
sc.close();
out.flush();
out.close();
}
}
L1-008 求整数段和
格式化输出三步法:
- 区间遍历:从A到B逐个数字累加求和
- 格式控制:每个数占5字符宽度(
%5d
),每满5个自动换行 - 边缘处理:最后无论是否满5个都补换行,确保"Sum="另起行
import java.io.*;
import java.util.*;
public class Main {
static BufferedReader sc = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
static String[] ss; // 输入分割缓存
static String s; // 单行输入缓存
public static void main(String[] args) throws IOException {
// 读取输入并分割为A、B两个整数
ss = sc.readLine().split(" ");
int A = Integer.parseInt(ss[0]);
int B = Integer.parseInt(ss[1]);
int sum = 0; // 累计总和
int count = 0; // 当前行数字计数器
// 主循环:遍历区间[A,B]的所有数字
for (int i = A; i <= B; i++) {
sum += i; // 累加求和
out.printf("%5d", i); // 每个数字占5字符宽度(右对齐)
count++;
// 每满5个数字换行(包括最后一行的完整换行)
if (count % 5 == 0) out.println();
}
// 补足最后一行的换行(当最后一行不足5个时)
if (count % 5 != 0) out.println();
// 输出总和(格式严格匹配题目要求)
out.print("Sum = " + sum);
sc.close();
out.flush();
out.close();
}
}
L1-009 N个数求和
分步累加化简法
- 初始化:读取第一个分数并化简
- 逐次累加:
- 通分计算:
新分子 = a*y + x*b
,新分母 = b*y
- 立即化简:用最大公约数约分,确保分母为正
- 通分计算:
- 输出决策:
- 整数 → 直接输出
- 假分数 → 转为带分数(如
5/2 → 2 1/2
) - 真分数 → 直接输出(如
3/4
)
核心优化:每次运算后立即约分,避免数值溢出,确保计算稳定性。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt(); // 读取分数个数
long a = 0, b = 1; // 累加结果的分子和分母
// 处理第一个分数(单独处理避免循环边界问题)
String[] firstFraction = scanner.next().split("/");
a = Long.parseLong(firstFraction[0]);
b = Long.parseLong(firstFraction[1]);
long[] simplified = simplifyFraction(a, b); // 初始化简化结果
a = simplified[0];
b = simplified[1];
// 逐个累加后续分数
for (int i = 1; i < N; i++) {
String[] fraction = scanner.next().split("/");
long x = Long.parseLong(fraction[0]); // 当前分子
long y = Long.parseLong(fraction[1]); // 当前分母
// 分数加法公式:a/b + x/y = (a*y + x*b)/(b*y)
long numerator = a * y + x * b;
long denominator = b * y;
simplified = simplifyFraction(numerator, denominator);
a = simplified[0]; // 更新累加分子
b = simplified[1]; // 更新累加分母
}
// 结果格式化输出
if (a % b == 0) { // 情况1:结果为整数
System.out.println(a / b);
} else {
long integerPart = a / b; // 提取整数部分
if (integerPart != 0) { // 情况2:带分数(如3 1/2)
System.out.print(integerPart + " ");
System.out.println((a % b) + "/" + b);
} else { // 情况3:真分数(如2/5)
System.out.println(a + "/" + b);
}
}
}
// 分数化简(核心方法)
private static long[] simplifyFraction(long a, long b) {
long g = gcd(Math.abs(a), Math.abs(b)); // 计算最大公约数
a /= g; // 约分分子
b /= g; // 约分分母
// 确保分母为正(数学规范)
if (b < 0) {
a *= -1;
b *= -1;
}
return new long[]{a, b};
}
// 欧几里得算法求最大公约数
private static long gcd(long a, long b) {
while (b != 0) { // 辗转相除
long temp = b;
b = a % b;
a = temp;
}
return a;
}
}
L1-010 比较大小
- 数据读取:读取一行输入,分割为3个整数
- 快速排序:使用
Arrays.sort()
进行升序排列 - 定向输出:按
最小值->中位数->最大值
格式拼接字符串
import java.io.*;
import java.util.*;
public class Main {
static BufferedReader sc = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
static String[] ss; // 输入分割缓存
static String s;
public static void main(String[] args) throws IOException {
// 读取输入并分割为3个整数
ss = sc.readLine().split(" "); // 按空格分割输入
int[] nums = new int[3]; // 存储三个数字的数组
// 转换字符串为整数
for(int i=0;i<3;i++) {
nums[i] = Integer.parseInt(ss[i]);
}
// 升序排序(时间复杂度O(nlogn))
Arrays.sort(nums);
// 格式化输出(严格按"a->b->c"格式)
out.print(nums[0]+"->"); // 最小值
out.print(nums[1]+"->"); // 中间值
out.print(nums[2]); // 最大值
out.println(); // 换行符结尾
sc.close();
out.flush();
out.close();
}
}