更多的是交流和自己做笔记用
HJ35蛇形矩阵
题目如下:
首先可以观察规律暴力输出:
这是我第一次写的,比较没有逻辑,因为我个人会有点逃避性使用多维数组。
package OnlineTest.easy;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class HJ35 {
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
//获取行数
int line = Integer.parseInt(bf.readLine());
//
int first = 1;
int cal=first;
int lineNext;
for (int i = 0; i < line; i++) {//输出第i行
cal = cal + i;//输出第i行的第一个数
lineNext=cal;
System.out.print(cal+" ");
for (int j = 1; j < line - i; j++) {//输出第i行除了第一个数
lineNext=lineNext+(i+1)+j;
System.out.print(lineNext+ " ");
}
System.out.println();//断行;
}
}
}
这是我又试着用多维数组写出来的。
int [] [] a 就把前一个[]想成是有多少行,后一个就是针对第i行而言,这个一行有多少个元素,有点这个意思:
(写完感觉也差不多)
package OnlineTest.easy;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Calendar;
import java.util.Scanner;
public class HJ35 {
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
//获取行数
int line = Integer.parseInt(bf.readLine());
int[][] marix = new int[line][];
int o=1;
int ColNextNumber=o;
int RowNextNumber;
for (int i = 0; i < line; i++) {
marix[i] = new int[line - i];
marix[i][0] = ColNextNumber;
RowNextNumber=ColNextNumber;
for (int j = 1; j < marix[i].length; j++) {
RowNextNumber=RowNextNumber+(i+1)+j;
marix[i][j] =RowNextNumber;
}
//下一行的
ColNextNumber = ColNextNumber + (i + 1);
}
for (int[] row : marix) {
for (int cal : row) {
System.out.print(cal+" ");
}
System.out.println();
}
}
}
HJ53 杨辉三角的变形
可惜用数组会发生heap溢出错误,如下。因此需要更改算法
package OnlineTest.easy;
import java.util.Scanner;
public class HJ53 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
//获取行数
int lines = sc.nextInt();
//建立一半的列
int col =lines;
//构建一个的矩阵
int[][] m = new int[lines][col];
//填充第一行
for (int i = 0; i < m[0].length; i++) {
m[0][i] = 0;
}
m[0][col-1]=1;
//从第二行起,遍历每一行
for (int i = 1; i < lines; i++) {
//不是最后一行
if (i < lines - 1) {
m[i][0]=0;
m[i][1] = 1;
}
//是最后一行
else {
m[i][0]=1;
}
//填充该行后面的数字
for (int k = 1; k <=col - 2; k++) {
m[i][k] = m[i - 1][k - 1] + m[i - 1][k] + m[i - 1][k + 1];
}
m[i][col-1]=m[i-1][col-2]+m[i-1][col-2]+m[i-1][col-1];
}
//矩阵构造完毕;可以输出检查
/* for (int[] x : m) {
for (int y : x) {
System.out.print(y+" ");
}
System.out.println();
}*/
//输出第一个偶数出现的位置
for (int i = 0; i < col; i++) {
if (m[lines-1][i] % 2 == 0) {
System.out.print(i+1);
break;
}
if (i == col- 1) {
System.out.println(-1);
}
}
}
}
}
放苹果问题(递归)
m个苹果放进n个盘子,m,n可以为0,例如4个苹果放进3个盘子,{1,2,1}和{2,1,1}是一种方法。
分析:
设f(m,n)为将m个苹果放到n个盘子里面的放法总数,m,n>=0;
分为两种情况:至少有一个盘子空着+所有盘子都不空着
(1)至少有一个盘子空,可以每次减少一个盘子来递归,因为,没减少一个空盘子,不影响放法的增减。也就是f(m,n-1)
(2)所有盘子都不空着,可以每次减少一层来递归。因为,每个盘子都有苹果的话,相当于这一层的底数都是1,减少这一层基数后,不影响放法的增减。也就是f(m-n,n);因此,递归表达式为: f(m,n)=f(m,n-1)+f(m-n,n)
结束条件:所有至少有一个盘子为空的情况会递归到所有盘子都不空着的情况;所有盘子都不空着的情况会递归到至少有一个不会为空的清空,循环往复,会递归到,只有一个盘子一个苹果,也就是(1,1),再递归就是只有0个苹果,一个盘子,因此结束条件:
f(0,0)=1 ;
f(0,n)=1;
f(1,1)=1;
package OnlineTest.easy;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class HJ61 {
/*分析:
设f(m,n)为将m个苹果放到n个盘子里面的放法总数,m,n>=0;
分为两种情况:至少有一个盘子空着+所有盘子都不空着
(1)至少有一个盘子空,可以每次减少一个盘子来递归,因为,没减少一个空盘子,不影响放法的增减。也就是f(m,n-1)
(2)所有盘子都不空着,可以每次减少一层来递归。因为,每个盘子都有苹果的话,相当于这一层的底数都是1,减少这一层基数后,不影响放法的增减。也就是f(m-n,n);
因此,递归表达式为:
f(m,n)=f(m,n-1)+f(m-n,n)*/
public static void main(String[] args)throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] s = br.readLine().split(" ");
int apple, plate;
apple = Integer.parseInt(s[0]);
plate = Integer.parseInt(s[1]);
System.out.println(count(apple,plate));
}
public static int count(int m, int n) {
if (m < 0||n<=0) {
return 0;
} else if (m ==1 || n == 1|| m==0) {//m=0的时候也算一种方法!
return 1;
}
else {
return count(m, n - 1) + count(m - n, n);
}
}
}
难点就是找递归表达式以及终止条件,多思考多练。
表示数字
这题就是,怎么说,会正则的话就会很简单…
还是先附上自己写的代码,然后看了看大佬的代码,补了一下正则表达式;
package OnlineTest.easy;
import java.util.Scanner;
public class HJ96 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
StringBuilder s = new StringBuilder(sc.nextLine());
int length = s.length();
int a,b;
a=0;
for (int i = 0; i < length;i=a) {
char c = s.charAt(a);
//如果是数字
if (Character.isDigit(c)) {
//插入数字
//注意,inser(offest,char)中的offset指的是第几个,不是下标
s.insert(a, '*');
//a仍指向第一个数字
a = a + 1;
//b和a指向一个数字
b = a;
//后指针遍历到文末
//总长度已经增加1个了
length++;
while (b < length && Character.isDigit(s.charAt(b))) {
b++;
continue;
}
s.insert(b, '*');
length += 1;
a = b + 2;
} else {
a++;
}
}
System.out.println(s);
}
}
}
这是正则
package OnlineTest.easy;
import java.util.Scanner;
public class HJ96 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
String s = sc.nextLine();
//添加一个加号,才能把连续的数字看成是一体的
String re = "([0-9]+)";
//$1表示正则表达式中第一个()表达式中匹配的内容
System.out.println(s.replaceAll(re, "*$1*"));
}
}
}
统计字符(涉及Comparator方法)
题目不难,主要下个用比较器来做做看
package OnlineTest.easy;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class HJ102 {
public static void main(String[] args) throws IOException {
/*思路:
* (1)集合(字母,次数)
* (2)compartor比较器 */
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder(br.readLine());
HashMap<String, Integer> hm = new HashMap<>();
for (int i = 0; i < sb.length(); i++) {
String s = String.valueOf(sb.charAt(i));
if (hm.containsKey(s)) {
int t = hm.get(s);
t++;
hm.put(s, t);
}
else {
hm.put(s, 1);
}
}
List<stringO> list = new LinkedList<>();
hm.forEach((k,v)->{
list.add(new stringO(k, v));
});
Collections.sort(list, new stringOComparator());
list.forEach(o->{
System.out.print(o.s);
});
}
}
class stringO{
int times;
String s;
public stringO(String s,int times) {
this.times = times;
this.s = s;
}
@Override
public String toString() {
return "stringO{" +
"times=" + times +
", s='" + s + '\'' +
'}';
}
}
class stringOComparator implements Comparator {
@Override
public int compare(Object obj1, Object obj2) {//参数要一致,才算
stringO o1 = (stringO) obj1;
stringO o2 = (stringO) obj2;
//次数大的排在前面
if (o1.times > o2.times) {
return -1;
} else if (o1.times < o2.times) {
return 1;
} else {
//比较ASCii
char c1 = o1.s.charAt(0);
char c2 = o2.s.charAt(0);
if (c1 > c2) {
return 1;
} else if (c1 < c2) {
return -1;
} else {
return 0;
}
}
}
}
输出单向链表中倒数第k个结点
考察:用java实现单链表创建
package OnlineTest.easy;
import java.util.Scanner;
public class HJ51 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int length = sc.nextInt();
Node head = new Node(-1);//定义头节点
Node p=head;//p指针指向head
for (int i = 0; i < length; i++) {
int value = sc.nextInt();
p.next = new Node(value);
p = p.next;//移动p指针
}
int k = sc.nextInt();
for (int i = 0; i < length - k + 1; i++) {
head=head.next;
}
System.out.println(head.data);
}
}
}
class Node {
/*定义节点*/
int data;
Node next;
public Node(int data) {
this.data = data;
this.next = null;
}
}