1. 求解n阶螺旋矩阵问题
【问题描述】 创建n阶螺旋矩阵并输出。
【输入描述】输入包含多个测试用例,每个测试用例为一行,包含一个正整数n(1≤n≤50),以输入0表示结束。
【输出描述】每个测试用例输出n行,每行包括n个整数,整数之间用一个空格分隔。
【输入样例】4
【输出样例】1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
public class Solution1 {
/**
* 目前已知最优雅的写法
* Left-Right-Top-Down螺旋模板
*/
public int[][] CreateSpiral(int n) {
int[][] res = new int[n][n];
int L = 0;
int R = n - 1;
int T = 0;
int D = n - 1;
int index = 1;
int remain = n * n;
while (remain > 0) {
for (int i = L; i <= R && remain > 0; i++) {
res[T][i] = (index++);
remain--;
}
T++;
for (int i = T; i <= D && remain > 0; i++) {
res[i][R] = (index++);
remain--;
}
R--;
for (int i = R; i >= L && remain > 0 ; i--) {
res[D][i] = (index++);
remain--;
}
D--;
for (int i = D; i >= T && remain > 0; i--) {
res[i][L] = (index++);
remain--;
}
L++;
}
return res;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (true) {
int n = sc.nextInt();
if (n == 0) {
break;
}
int[][] res = new Solution1().CreateSpiral(n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.print(res[i][j] + " ");
}
System.out.println();
}
}
}
}
2. 求解幸运数问题
【问题描述】小明同学学习了不同的进制之后,拿起了一些数字做起了游戏。小明同学知道,在日常生活中我们最常用的是十进制数,而在计算机中,二进制数也很常用。现在对于一个数字x,小明同学定义出了两个函数f(x)和g(x)。 f(x)表示把x这个数用十进制写出后各个数位上的数字之和。如f(123)=1+2+3=6。 g(x)表示把x这个数用二进制写出后各个数位上的数字之和。如123的二进制表示为1111011,那么,g(123)=1+1+1+1+0+1+1=6。 小明同学发现对于一些正整数x满足f(x)=g(x),他把这种数称为幸运数,现在他想知道,小于等于n的幸运数有多少个?
【输入描述】n(n≤100000)。
【输入描述】小于等于n的幸运数个数。
【输入样例】21
【输入样例】3
public class Solution2 {
/**
* 每一个数都判断是否是LuckyNumber即可,非常简单~
*/
public int getLuckyNumber(int n) {
int cnt = 0;
for (int i = 1; i <= n; i++) {
cnt += (f(i) == g(i) ? 1 : 0);
}
return cnt;
}
private int f(int n) {
if (n < 10) {
return n;
}
return n % 10 + f(n / 10);
}
private int g(int n) {
if (n < 2) {
return n;
}
return n & 1 + g(n >> 1);
// 位运算永远的神
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
System.out.println(new Solution2().getLuckyNumber(n));
}
}
3. 求解回文序列问题
【问题描述】如果一个数字序列逆置后跟原序列是一样的,则称这样的数字序列为回文序列。例如,{1,2,1}、{15,78,78,15}、{11,2,11}是回文序列,而{1,2,2}、{15,78,87,51}、{112,2,11}不是回文序列。现在给出一个数字序列,允许使用一种转换操作:选择任意两个相邻的数,然后从序列中移除这两个数,并将这两个数的和插入到这两个之前的位置(只插入一个和)。对于所给序列求出最少需要多少次操作可以将其变成回文序列。
【输入描述】:输入为两行,第1行为序列长度 n(1≤n≤50),第2行为序列中的n个整数item[i] (1≤item[i]≤1000),以空格分隔。
【输出描述】:输出一个数,表示最少需要的转换次数。
【输入样例】4
1 1 1 3
【输出样例】2
public class Solution3 {
/**
* 每次计算最外面的一层,递归内层
*/
public int trans2palindrome(int[] arr, int L, int R) {
if (L >= R) {
return 0;
}
int res = 0;
int sumL = arr[L++];
int sumR = arr[R--];
while (L <= R) {
if (sumL < sumR) {
sumL += arr[L++];
res++;
} else if (sumL > sumR) {
sumR += arr[R--];
res++;
} else {
break;
}
}
return res + trans2palindrome(arr, L, R);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int len = sc.nextInt();
int[] arr = new int[len];
for (int i = 0; i < len; i++) {
arr[i] = sc.nextInt();
}
System.out.println(new Solution3().trans2palindrome(arr, 0, len -1));
}
}
4. 求解投骰子游戏问题
【问题描述】玩家根据骰子的点数决定走的步数,即骰子点数为1时可以走一步,点数为2时可以走两步,点数为n时可以走n步。求玩家走到第n步(n≤骰子最大点数且投骰子的方法唯一)时总共有多少种投骰子的方法。
【输入描述】:输入包括一个整数n(1≤n≤6)。
【输出描述】:输出一个整数,表示投骰子的方法数。
【输入样例】:6
【输出样例】:32
public class Solution4 {
/**
* 回溯的最简单最初始版本———不需要记录路径,仅需要记录个数
*/
public int ThrowDice(int n) {
return traceBack(n);
}
private int traceBack(int remain) {
if (remain == 0) {
return 1;
}
int sum = 0;
for (int i = 1; i <= 6 && i <= remain; i++) {
sum += traceBack(remain - i);
}
return sum;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
System.out.println(new Solution4().ThrowDice(n));
}
}
⭐️ 这一定是全网最优美的Java解法 >_<