进入考场先调提示,提升敲代码效率:
Window ——> Preferences ——> Java ——> Editor ——> Content Assist,在如下的地方添加26个小写字母,保存退出就可以了。
日期:
package Date;
import java.util.Scanner;
/*
* 日期:
* 求闰年
* 这个就不说了都懂.....
*/
public class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
if (targetdate(scanner.nextInt())) {
System.out.println("YES");
}
}
static boolean targetdate(int year) {
if (year%400==0||(year%4==0&&year%100!=0)) {
return true;
}
return false;
}
}
/*
* 示例:
* 2020
* YES
*/
全排:
package Permutations;
/*
* 全排列1:
* 利用swap进行交互的全排
* 优点:简洁,明确效率高
* 缺点:遇到一些需要重复数据的问题不好解决。
*/
public class Main {
static int nums[]= {1,2,3,4,5};
public static void main(String[] args) {
dfs(0);
}
static void dfs(int step) {
if (step==nums.length) {
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i]+" ");
}
System.out.println();
return;
}
for (int i = step; i < nums.length; i++) {
swap(i,step);
dfs(step+1);
swap(i, step);
}
}
static void swap(int a,int b) {
int mid=nums[a];
nums[a]=nums[b];
nums[b]=mid;
}
}
/*
* 部分示例:
* 1 2 3 4 5
* 1 2 3 5 4
* 1 2 4 3 5
* 1 2 4 5 3
* 1 2 5 4 3
* 1 2 5 3 4
* 1 3 2 4 5
* 1 3 2 5 4
*/
package Permutations;
/*
* 全排列2:
* 利用targetnums数组进行记录是否标记过
* 优点:可以解决大部分重复无重复问题
* 缺点:没有全排1那么简洁,效率应该低一点,包含0的需要计算好边界。
*/
public class Main2 {
static int n=5;
static int nums[]= new int[n];
static int targetnums[]=new int[n];
public static void main(String[] args) {
dfs(0);//要排列不包含0的需要自己为1
}
static void dfs(int step) {
if (step==n) {
for (int i = 0; i < nums.length; i++) {//要排列不包含0的需要自己为1
System.out.print(nums[i]+" ");
}
System.out.println();
return;
}
for (int i = 0; i < nums.length; i++) {//要排列不包含0的需要自己为1
if (targetnums[i]==0) {
targetnums[i]=1;
nums[step]=i;
dfs(step+1);
targetnums[i]=0;
}
}
}
}
/*
* 部分示例:
* 0 1 2 3 4
* 0 1 2 4 3
* 0 1 3 2 4
* 0 1 3 4 2
* 0 1 4 2 3
*/
并查集连通:
package Union_Find;
/*
* 并查集
* 利用并查集,比直接硬模拟更高效,傻傻的我遇到并查集问题一开始就是直接硬模拟
*/
public class Main {
static int n=5;
static int nums[]=new int[n];
public static void main(String[] args) {
init();
merge(1, 2); //连通1-2
merge(3, 4); //连通3-4;
System.out.println(connect(1,3));//false
System.out.println(connect(1,2));//true
System.out.println(connect(3,4));//true
}
static void init() { //初始化
for (int i = 0; i < nums.length; i++) {
nums[i]=i;
}
}
static int far(int num) { //寻找根节点
if (nums[num]!=num) {
return far(nums[num]);
}
return num;
}
static void merge(int a,int b) { //合并
int fara=far(a);
int farb=far(b);
if (fara!=farb) {
nums[b]=fara;
}
}
static boolean connect(int a,int b) { //是否连通
int fara=far(a);
int farb=far(b);
if (fara==farb) {
return true;
}
return false;
}
}
数论:
来到我们的重点了......数论是很多的,这里我只写出来我练习时候出现比较频繁的一些用到的数论公式。
-
最大公约数,最小公倍数
package Number_Theory; public class Main { public static void main(String[] args) { System.out.println(gcd(20, 8)); //4 System.out.println(lcm(20, 8)); //40 } static int gcd(int a,int b) { //最大公约数 return a%b==0?b:gcd(b,a%b); } static int lcm(int a,int b) { //最小公倍数 return a*b/gcd(a, b); } }
-
素数筛
package Number_Theory; /* * 素数筛(质数)也叫打表法 * 快一点的思想 :从2开始,每个质数的倍数标记成合数。 * 原理:埃氏筛法 */ public class Main2 { static int n=10000; static int nums[]=new int[n]; public static void main(String[] args) { prime(); for (int i = 2; i < nums.length; i++) { if (nums[i]==1) { System.out.println(i+" "); } } } static void prime() { for (int i = 2; i < nums.length; i++) { if (nums[i]==0) { nums[i]=1; //标记为素数(1) for (int j = i+i; j < nums.length; j+=i) { nums[j]=-1;//标记为合数(-1) } } } } } /* * 部分示例: * 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23 */
-
唯一分解定理
package Number_Theory; /* * 唯一分解定理 * 原理:对任何一个整数n都可以将其拆分有n = P1^a1 * P2^a2 * …………* (P1 < P2 < ……Pn);Pi是素数 * 那么n的因子个数为=(a1+1)(a2+1)(a3+1)...... * n的所有因子之和为(q1^ 0+q1^ 1+q1^ 2…q1^ a1)(q2^ 0+q2^ 1+q2^ 2…q2^ a2)…*(qn^ 0+qn^ n+qn^ 2 …qn^ an); */ public class Main3 { static int n=1000; static int primenums[]=new int[n]; static int index=0; static int nums[]=new int[n]; public static void main(String[] args) { int num=20;//例子:20 prime(); split(num); // 2^2*5^1=20; //1 0 //2 2 //3 0 //4 0 //5 1 //6 0 System.out.println(number(num)); //20的因子个数为6 //(2+1)*(1+1) //1,2,4,5,10,20 System.out.println(numbersum(num));//20的因子之和 42 //(1+2+2^2)*(1+5) } static void prime() { //打表法 int prime[]=new int[n]; for (int i = 2; i < prime.length; i++) { if (prime[i]==0) { prime[i]=1; //标记为素数(1) for (int j = i+i; j < prime.length; j+=i) { prime[j]=-1;//标记为合数(-1) } } } //打完表把prime中为1(质数)的数取到另一个数组保存. for (int i = 0; i < prime.length; i++) { if (prime[i]==1) { primenums[index++]=i; } } } static void split(int num) { //求num=P1^a1 * P2^a2 * …………* (P1 < P2 < ……Pn); //Pi是素数,保存到nums中 for (int j = 0; j < index; j++) { while (num%primenums[j]==0) { nums[primenums[j]]++; num/=primenums[j]; } if (num==0) { break; } } } static int number(int num) { //求因子num个数 int sum=1; for (int i = 1; i <=num; i++) { if (nums[i]!=0) { sum*=(nums[i]+1); } } return sum; } static int numbersum(int num) { //求num因子之和 int sum=1; for (int i = 1; i <=num; i++) { int mid=0; if (nums[i]!=0) { for (int j = 0; j <=nums[i]; j++) { mid+=Math.pow(i, j); } sum*=mid; } } return sum; } }
-
康托展开公式
package Number_Theory; /* * 康托展开公式 *X = A[0] * (n-1)! + A[1] * (n-2)! + … + A[n-1] * 0! * A[n] 指的是位于位置n后面的数小于A[n]值的个数,后面乘的就是后面还有多少个数的阶乘 * 例如:1,2,3,4,5排列组合,求34152的排名第几位, 其中A[1]是2,要乘的阶乘则为3!.因为从1这个位置(值为4) * 开始往后比4小的只有2个数(1和2),所以A[1]为2,后面还有3个位置(1,5,2)按顺序来,则就是2*3!。 * 这只是A[1] * (n-2)!的一个例子,每个位置都要算 */ public class Main4 { static int nums[]= {3,4,1,5,2}; //1,2,3,4,5排列组合,求34152的排名第几位 public static void main(String[] args) { System.out.println(cantor()); //输出61则,34152,在12345排列组合中排61位. } static int cantor() { int sum=0; for (int i = 0; i < nums.length; i++) { int Anum=0,n=1,m=1; //Anum记录A[],n记录(n-1)! for (int j = i+1; j < nums.length; j++) { if (nums[i]>nums[j]) { Anum++; } n*=m; m++; } sum+=Anum*n; } return sum; } }
-
海伦公式
package Number_Theory; /* * 海论公式 * 给出三角形三边可以求三角形面积 * 首先p为三角形的半周长 则 p=(a+b+c)/2 * 面积为S=sqrt(p(p-a)(p-b)(p-c)) * 用法:在三角形不是直角三角形,也求不到高的情况下 */ /* * 给一道例题 * * * 已知三角形三个顶点在直角坐标系下的坐标分别为: (2.3, 2.5) (6.4, 3.1) (5.1, 7.2) 求该三角形的面积。 注意,要提交的是一个小数形式表示的浮点数。 要求精确到小数后3位,如不足3位,需要补零。 */ public class Main5 { public static void main(String[] args) { double a=Math.sqrt(Math.pow((3.1-2.5),2)+Math.pow((6.4-2.3),2)); double b=Math.sqrt(Math.pow((5.1-2.3),2)+Math.pow((7.2-2.5),2)); double c=Math.sqrt(Math.pow((6.4-5.1),2)+Math.pow((7.2-3.1),2)); System.out.println(a); System.out.println(b); System.out.println(c); double p=(a+b+c)/2; System.out.println(Math.sqrt(p*(p-a)*(p-b)*(p-c)));//答案 8.795 } }