题目一:矩阵乘法
问题描述:
给定一个N阶矩阵A,输出A的M次幂(M是非负整数)(时间限制:1.0s,内存限制:512.0MB,)
例如:
A =
1 2
3 4
A的2次幂
7 10
15 22
输入、输出格式:
第一行是一个正整数N、M(1<=N<=30, 0<=M<=5),表示矩阵A的阶数和要求的幂数。
接下来N行,每行N个绝对值不超过10的非负整数,描述矩阵A的值。
输出共N行,每行N个整数,表示A的M次幂所对应的矩阵。相邻的数之间用一个空格隔开。
解决思路:
1.写出两个矩阵相乘的函数再执行相应次数即可。
2.需要注意矩阵的0次幂是单位矩阵。
解决代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // 阶数
int m = sc.nextInt(); // 幂数
int[][] arr1 = new int[n][n];
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
arr1[i][j] = sc.nextInt();
}
}
if(m == 0){
for(int i = 0; i < n;i++){
for(int j = 0; j < n;j++){
if(i == j)
System.out.print(1 + " ");
else
System.out.print(0 + " ");
}
System.out.println();
}
System.exit(0);
}
int[][] arr2 = arr1;
for(int i = 1; i < m; i++) {
arr2 = multiply(arr1, arr2);
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
System.out.print(arr2[i][j] + " ");
}
System.out.println();
}
}
/**
* 两矩阵相乘
* @param a
* @param b
* @return
*/
private static int[][] multiply(int[][] a, int[][] b) {
int length = a.length;
int[][] res = new int[length][length];
for(int i = 0; i < length; i++) {
for (int j = 0; j < length; j++) {
for (int k = 0; k < length; k++) {
res[i][j] += a[i][k] * b[k][j]; // 通过构建i行j列的矩阵即可推出该公式
}
}
}
return res;
}
}
题目二:阶乘计算
问题描述:
输入一个正整数n,输出n!的值。(时间限制:1.0s,内存限制:512.0MB)
其中n!=123…n
输入、输出格式:
输入包含一个正整数n,n<=1000。
输出n!的准确值。
解决思路:
使用BigInteger类即可。
解决代码:
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
BigInteger bg = new BigInteger("1");
for(int i = 1; i <= n; i++){
String s = String.valueOf(i);
bg = (new BigInteger(s)).multiply(bg);
}
System.out.println(bg);
}
}
题目三:高精度加法
问题描述:
输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。(时间限制:1.0s,内存限制:512.0MB)
输入、输出格式:
输入包括两行,第一行为一个非负整数a,第二行为一个非负整数b。两个整数都不超过100位,两数的最高位都不是0。
输出一行,表示a + b的值。
解决思路:
使用BigInteger类即可。
解决代码:
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s1 = sc.next();
String s2 = sc.next();
BigInteger bg1 = new BigInteger(s1);
BigInteger bg2 = new BigInteger(s2);
System.out.println(bg1.add(bg2));
}
}
题目四:Huffuman树
问题描述:
Huffman树在编码中有着广泛的应用。在这里,我们只关心Huffman树的构造过程。(时间限制:1.0s,内存限制:512.0MB)
给出一列数{pi}={p0, p1, …, pn-1},用这列数构造Huffman树的过程如下:
- 找到{pi}中最小的两个数,设为pa和pb,将pa和pb从{pi}中删除掉,然后将它们的和加入到{pi}中。这个过程的费用记为pa + pb。
- 重复步骤1,直到{pi}中只剩下一个数。
在上面的操作过程中,把所有的费用相加,就得到了构造Huffman树的总费用。
本题任务:对于给定的一个数列,现在请你求出用该数列构造Huffman树的总费用。
例如,对于数列{pi}={5, 3, 8, 2, 9},Huffman树的构造过程如下:
- 找到{5, 3, 8, 2, 9}中最小的两个数,分别是2和3,从{pi}中删除它们并将和5加入,得到{5, 8, 9, 5},费用为5。
- 找到{5, 8, 9, 5}中最小的两个数,分别是5和5,从{pi}中删除它们并将和10加入,得到{8, 9, 10},费用为10。
- 找到{8, 9, 10}中最小的两个数,分别是8和9,从{pi}中删除它们并将和17加入,得到{10, 17},费用为17。
- 找到{10, 17}中最小的两个数,分别是10和17,从{pi}中删除它们并将和27加入,得到{27},费用为27。
- 现在,数列中只剩下一个数27,构造过程结束,总费用为5+10+17+27=59。
输入、输出格式:
输入的第一行包含一个正整数n(n<=100)。
接下来是n个正整数,表示p0, p1, …, pn-1,每个数不超过1000。
输出用这些数构造Huffman树的总费用。
解决思路:
用ArrayList存储这些值,计算出列表中最小两个值的和之后将这两个值移出列表,并将和存入列表。
解决代码:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
ArrayList<Integer> arr = new ArrayList();
for(int i = 0; i < n; i++) {
arr.add(sc.nextInt());
}
int sum = 0;
while(n > 1) {
sum += min(arr);
n--;
}
System.out.println(sum);
}
/**
* 求一个数组中最小两个数的和
* @param a
* @return
*/
private static int min(ArrayList<Integer> a) {
Collections.sort(a);
int sum = 0;
for(int i = 0; i < 2; i++) {
sum += a.get(i);
}
a.remove(0);
a.remove(0);
a.add(sum);
return sum;
}
}