时间复杂度
我觉得关于时间复杂度没有什么好讲的,大一的时候程序基础大家应该都了解,这部分可以直接跳过啦。
枚举
定义:枚举算法我们也称之为穷举算法,这种算法就是在解决问题的时候去使用所有的方式去解决这个问题,会通过推理去考虑事件发生的每一种可能,最后推导出结果。
-
优点:简单粗暴,它暴力的枚举所有可能,尽可能地尝试所有的方法。
-
缺点:大部分题目使用枚举算法拿不到满分。
例题
1.标题统计
我的解法:
import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改 public class Main { public static void main(String[] args) { Scanner scan = new Scanner(System.in); //在此输入您的代码... int count = 0; while(scan.hasNext()) { char[] arr = scan.nextLine().toCharArray(); count+=arr.length; for(int i=0;i<arr.length;i++) { if(arr[i]==' ') { --count; } } } System.out.print(count); scan.close(); } }
其实这些题都相对比较简单,因为一天学习的开始都是要慢慢来,可以稍微过一遍就好,但是贵在每日坚持!
2.计数问题
import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改 public class Main { public static void main(String[] args) { Scanner scan = new Scanner(System.in); //在此输入您的代码... int n = scan.nextInt(); int x = scan.nextInt(); String a = String.valueOf(x); int count = 0; char[][] arr = new char[n+1][]; for(int i=1;i<=n;i++) { arr[i] = String.valueOf(i).toCharArray(); } for(int i=1;i<=n;i++) { for(int j=0;j<arr[i].length;j++) { if(arr[i][j]== a.charAt(0)) { count++; } } } System.out.print(count); scan.close(); } }
这些题中总是有很多scan的读取数据的方法:这里需要同一总结。
3.next(),nextInt(),nextDouble(),nextLine
前三者可以认为是一类的。读到空格之前的部分。焦点不会移动到下一行,仍然处在这一行上。
next(),返回值是一个字符串
nextInt(),返回值是int
nextDouble(),返回值是double
当使用nextLine()方法时会读取改行从前到的所有的内容,包括换行符,然后把焦点移动到下一行的开头。也就是可以把空格,回车读出值为空。
所以说当前三种但凡跟nextLine()混着用的时候就要考虑多用一个nextLine()了来进行读取数据换行了。
4.质因数分解
关于质因数分解我想到了素数判断;
import java.util.Scanner; public class HomeWork { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入要判断的数字:"); int n = sc.nextInt(); int i = 2; for(;i <= Math.sqrt(n);i++){ if(n % i == 0){ System.out.println(n+"不是素数"); break; } } if(i >Math.sqrt(n)){ System.out.println(n+"是素数"); } } }
接下来是我对于这道题的解法:
import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改 public class Main { public static void main(String[] args) { Scanner scan = new Scanner(System.in); //在此输入您的代码... int n = scan.nextInt(); for(int i=2;i<Math.sqrt(n);i++) { if(n%i==0) { System.out.print(n/i); break; } } scan.close(); } }
5.小蓝的漆房
解法:暴力枚举 因为题目中已经限制了颜色的个数,最多60个。那么本题的一个比较容易理解的方法是枚举每一种颜色(即将所有房子变成60种颜色中的一种),计算60种情况下哪个情况下所需要的天数最少。
我的解法:
import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改 public class Main { public static void main(String[] args) { Scanner scan = new Scanner(System.in); //在此输入您的代码... int t = scan.nextInt(); for(int i=0;i<t;i++) { int n = scan.nextInt(); int k = scan.nextInt(); int []arr_ = new int[n]; for(int j=0;j<n;j++) { arr_[j] = scan.nextInt(); } int min = Integer.MAX_VALUE; for(int m=1;m<=60;m++) { int []arr = arr_.clone(); int count = 0; int index=0; while(index<n) { if(arr[index]==m) { ++index; continue; } else { count++; for(int p=0;p<k&&index<n;p++) { arr[index] = m; ++index; } } } if(min>count) min = count; } System.out.println(min); } scan.close(); } }
这道题看似暴力枚举,实际上还有不少的坑。比如每次要及时更新数组,
int []arr = arr.clone(); 这个才是深拷贝,若是int []arr = arr_是无济于事的。
在 Java 中实现数组复制分别有以下 4 种方法:
-
Arrays 类的 copyOf() 方法
-
Arrays 类的 copyOfRange() 方法
-
System 类的 arraycopy() 方法
-
Object 类的 clone() 方法
在以上四个方法中只有clone是深拷贝。
例题串处理
import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改 public class Main { public static void main(String[] args) { Scanner scan = new Scanner(System.in); //在此输入您的代码... char []arr = scan.nextLine().toCharArray(); char []expert = new char[2*arr.length]; int index=0; for(int i=0;i<arr.length;) { //多个空格情况 if(arr[i]==' ') { i++; if(index!=0) { expert[index++] = ' '; } while(arr[i]==' ') { i++; } continue; } //小写字母需要变的情况 //You中的Y字符串中的第一个字符需要大写 //And中的A遇到前面一个字符是空格需要大写 if((i>0&&arr[i-1]==' '&&arr[i]>='a'&&arr[i]<='z')||index==0&&arr[i]>='a'&&arr[i]<='z') { expert[index++]= (char) (arr[i++]^32); continue; } //小写字母不用变的情况 //You中的ou只看前一个字符是否是字母 //2005_program中的p看前一个字符是否为'_' //需要在if里面再进行判断字母后所跟的是不是数字,若为数字再赋值expert一个'_' if (i > 0 && i < arr.length && (arr[i-1] >= 'a' && arr[i-1] <= 'z' && arr[i] >= 'a' && arr[i] <= 'z') || (index > 0 && expert[index-1] == '_' && arr[i] >= 'a' && arr[i] <= 'z')) { if(i<arr.length-1&&arr[i+1]>='0'&&arr[i+1]<='9') { expert[index++]=arr[i++]; expert[index++]='_'; continue; } expert[index++]=arr[i++]; continue; } //数字的赋值情况 //一般遇到数字就直接赋值需要在if里面再进行判断数字后所跟的是不是字母,若为数字再赋值expert一个'_' if(arr[i]>='0'&&arr[i]<='9') { if(i<arr.length-1&&arr[i+1]>='a'&&arr[i+1]<='z') { expert[index++]=arr[i++]; expert[index++]='_'; continue; } expert[index++]=arr[i++]; continue; } i++; } for(int i=0;i<index;i++) { System.out.print(expert[i]); } scan.close(); } }
通过率百分之40。
DNA修正序列
import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub // 读入数据 Scanner sc = new Scanner(System.in); int n = sc.nextInt(); sc.nextLine(); char[] sq1 = sc.next().toCharArray(); sc.nextLine(); char[] sq2 = sc.next().toCharArray(); Map<Character, Integer> map = new HashMap<>(); map.put('A', 0); map.put('C', 1); map.put('G', 2); map.put('T', 3); int res = 0; for(int i = 0; i < n; ++i) { if(map.get(sq1[i]) + map.get(sq2[i]) != 3) { for(int j = i + 1; j < n; ++j) { if(map.get(sq1[i]) + map.get(sq2[j]) == 3 && map.get(sq1[j]) + map.get(sq2[i]) == 3) { char c = sq2[i]; sq2[i] = sq2[j]; sq2[j] = c; break; } } ++res; } } System.out.println(res); // 关闭资源 sc.close(); } }
注意在代码中并没有刻意指出需要将第二个序列的字符替换为A、C、G、T中的任意一个。因为循环后如果没有下面这种情况:
if(map.get(sq1[i]) + map.get(sq2[j]) == 3 && map.get(sq1[j]) + map.get(sq2[i]) == 3) { char c = sq2[i]; sq2[i] = sq2[j]; sq2[j] = c; break; }
也会进行res++;这时就包含了将第二个序列的字符替换为A、C、G、T中的任意一个的情况。
这种使用Hashtable来进行操作的方法很值得借鉴。
递归
数的计算
不太理解题目的意思,于是我搜了一下另外一种题目描述: 给出自然数n,要求按如下方式构造数列: 1.只有一个数字n的数列是一个合法的数列。 2.在一个合法的数列的末尾加入一个自然数,但是这个自然数不能超过该数列最后一项的一 半,可以得到一个新的合法数列。 也就是新加的数不能超过前一个数的一半,最后求序列有多少个数
import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class Main { public static int count = 0; public static void main(String[] args) { // TODO Auto-generated method stub // 读入数据 Scanner scan = new Scanner(System.in); int n = scan.nextInt(); count_num(n); System.out.println(count+1); scan.close(); } static void count_num(int n) { if(n/2==0) { return; } for(int i=n/2;i>=1;i--) { count++; count_num(i); } } }
计算函数值
import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scan = new Scanner(System.in); int x = scan.nextInt(); System.out.println(garden(x)); scan.close(); } static int garden(int x) { if(x==0) { return 1; } if(x%2==0) { return garden(x/2); }else { return garden(x-1)+1; } } }