写在前面:距离蓝桥杯省赛还有不到半月,个人整理一些常用算法,分享给大家。
public class LeastCommonMultiple {
//使用欧几里得算法求解数m和数n最大公约数
public int getGcd(int m,int n){
while(n > 0){
int temp = m % n;
m = n;
n = temp;
}
return m;
}
//求解数m和n和最小公倍数
public int getLcm(int m,int n){
int gcd = getGcd(m,n);
int result = m*n / gcd;
return result;
}
static int gcd(int[] a) {
int n = a.length;
int g = a[0];
for(int i=1;i
方法一:使用Math.round()函数,此处返回的是数字格式
float f=1.258;
int i=3;
float t=f*i;
float num=(float)(Math.round(t*100)/100.0);//如果要求精确4位就*10000然后/10000
方法二:使用DecimalFormat包,此处返回的是string类型
import java.text.DecimalFormat;
sum = 1.55555 //计算最终分数
DecimalFormat decimalFormat=new DecimalFormat(".00"); //如果小数不足2位,会以0补足.
String p=decimalFormat.format(sum);
//Math.floor()、Math.ceil()、BigDecimal都是Java中的取整函数,但返回值却不一样
Math.floor()
通过该函数计算后的返回值是舍去小数点后的数值
如:Math.floor(3.2)返回3
Math.floor(3.9)返回3
Math.floor(3.0)返回3
Math.ceil()
ceil函数只要小数点非0,将返回整数部分+1如:Math.ceil(3.2)返回4
Math.ceil(3.9)返回4
Math.ceil(3.0)返回3
boolean isleaf(int x){
return x%400==0||(x%4==0&&x%100!=0);
}
boolean isprime(int n){
if(n==1)return false;
for(int i=2;i*i
public class Test {
public void dateDiff(String startTime, String endTime, String format) {
//按照dao传入的格式生成一个simpledateformate对象
SimpleDateFormat sd = new SimpleDateFormat(format);
long nd = 1000*24*60*60;//一天的毫秒数
long nh = 1000*60*60;//一小时的毫秒数
long nm = 1000*60;//一分钟的毫秒数
long ns = 1000;//一秒钟的毫秒数long diff;try {
//获得两个时间的毫秒时间差异
diff = sd.parse(endTime).getTime() - sd.parse(startTime).getTime();
long day = diff/nd;//计算差多少天
long hour = diff%nd/nh;//计算差多少小时
long min = diff%nd%nh/nm;//计算差多少分钟
long sec = diff%nd%nh%nm/ns;//计算差多少秒//输出结果
System.out.println("时间相差:"+day+"天"+hour+"小时"+min+"分钟"+sec+"秒。");
public class TestIndexOf {
public static void main(String[] args) {
int num = getMaches("abcabcabcabca", "ca");
System.out.println(num);
}
public static int getMaches(String str,String substr){
int count = 0;//count用来接收子字符串substr在字符串str中出现的次数
int i = 0;
while(str.indexOf(substr,i) != -1) {
count++;
i=str.indexOf(substr, i)+substr.length();
}
return count;
}
}
static void f(int[] a) {
int n = a.length;
int l=0,r=n-1,ans=0;//一般上界需要自己构造
while(l<=r) {
int mid = l + (r-l)/2;
if(ok(a[mid])) {
r = mid-1;
ans = mid;
}else
l = mid+1;
}
System.out.println(ans);
}
static boolean ok(int x) {
return false;//按照题意写
}
static int mod=100000007;
/**
* 计算a的n次方(要求n>=0)
* @param a
* @param n
* @return
*/
public static long quickPow(long a,int n) {
long ans=1;
while(n>0) {
if((n&1)==1)
ans=ans*a%mod;
a=a*a%mod;
n>>=1;
}
return ans;
}
简单背包
import java.util.Scanner;
/*
* 有n件物品和容量为m的背包 给出i件物品的重量以及价值 求解让装入背包的物品重量不超过背包容量 且价值最大
特点 但它的特点是每个物品只能选用一次
* */
public class situation01 {
//01背包
public static void main(String args[]){
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();//物品的总数量
int m = scanner.nextInt();//背包的重量
int a[] = new int[50001];//重量
int b[] = new int[50001];//价值
for (int i=1;i<=n;i++){
a[i] = scanner.nextInt();
b[i] = scanner.nextInt();
}
int f[] = new int[50001];
for (int i=1; i<=n; i++){
for (int j=m; j>=a[i]; j--){//完全背包只修改了这一句的顺序,其余不变for(int j=a[i]; j<=m; j++)
if (f[j-a[i]]+b[i]>f[j])//多重背包就是在a[i]和b[i]前面加了数量
f[j] = f[j-a[i]]+b[i];
}
}
System.out.println(f[m]);
}
}
完全背包
import java.util.Scanner;
/*
* 有n件物品和容量为m的背包 给出i件物品的重量以及价值 求解让装入背包的物品重量不超过背包容量 且价值最大
特点 题干看似与01一样 但它的特点是每个物品可以无限选用
* */
public class situation02 {
public static void main(String args[]){
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();//物品的数量
int m = scanner.nextInt();//背包的重量
int a[] = new int[50001];
int b[] = new int[50001];
for (int i=1;i<=n;i++){
a[i] = scanner.nextInt();
b[i] = scanner.nextInt();
}
int f[] = new int[50001];
for (int i=1; i<=n; i++){
for (int j=a[i]; j<=m; j++){//完全背包只修改了这一句的顺序,其余不变for(int j=a[i]; j<=m; j++)
if (f[j-a[i]]+b[i]>f[j])
f[j] = f[j-a[i]]+b[i];
}
}
System.out.println(f[m]);
}
}
多重背包
import java.util.Scanner;
import static sun.swing.MenuItemLayoutHelper.max;
public class situation03 {
/*
* 多重背包
* 每件物品可以选择有限的次数
* */
public static void main(String args[]){
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt();//背包的重量
int n = scanner.nextInt();//物品的总数量
int[] a = new int[10001];//重量
int[] b = new int[10001];//价值
int[] c = new int[10001];//数量
for (int i=0; i=0; j--){
for (int k=0; k<=c[i]; k++){
if (j-k*a[i]<0) break;
f[j]= max(f[j],f[j-k*a[i]]+k*b[i]);
}
}
}
System.out.println(f[m]);
}
}
DFS
import java.awt.*;
import java.util.ArrayList;
public class DFS {
static int maxn=100;
static boolean vst[][] = new boolean[maxn][maxn]; // 访问标记
static int map[][] = new int[maxn][maxn]; // 坐标范围
ArrayList dir = new ArrayList<>(); //方向向量,(x,y)周围的四个方向
public static boolean CheckEdge(int x,int y) //边界条件和约束条件的判断
{
if(!vst[x][y] && ) // 满足条件
return true;
else // 与约束条件冲突
return false;
}
void dfs(int x,int y)
{
vst[x][y]=true; // 标记该节点被访问过
if(map[x][y]==) // 出现目标态G
{
...... // 做相应处理
return;
}
for(int i=0; i<4; i++)
{
if(CheckEdge(x+dir[i][0],y+dir[i][1])) // 按照规则生成下一个节点
dfs(x+dir[i][0],y+dir[i][1]);
}
return; // 没有下层搜索节点,回溯
}
public static void main(String[] args)
{
}
}
BFS
// 计算从起点 start 到终点 target 的最近距离
int BFS(Node start, Node target) {
Queue q; // 核心数据结构
Set visited; // 避免走回头路
q.offer(start); // 将起点加入队列
visited.add(start);
int step = 0; // 记录扩散的步数
while (q not empty) {
int sz = q.size();
/* 将当前队列中的所有节点向四周扩散 */
for (int i = 0; i < sz; i++) {
Node cur = q.poll();
/* 划重点:这里判断是否到达终点 */
if (cur is target)
return step;
/* 将 cur 的相邻节点加入队列 */
for (Node x : cur.adj())
if (x not in visited) {
q.offer(x);
visited.add(x);
}
}
/* 划重点:更新步数在这里 */
step++;
}
}
import java.util.Scanner;
public class Main{
static int N = 10, n ;
static boolean st[] = new boolean[N];
static int[] f = new int[N];
public static void dfs(int u){
if( u == n){
for(int i = 0; i < n; i ++)
System.out.print(f[i]+" ");
System.out.println();
return;
}
for(int i = 1; i <= n; i++)
if(!st[i]){
st[i] = true;
f[u] = i;
dfs( u + 1);
st[i] = false;
}
}
public static void main(String args[]){
Scanner reader = new Scanner(System.in);
n = reader.nextInt();
dfs(0);
}
}
import java.util.Scanner;
import java.util.Arrays;
/*
带重复元素的全排列
*/
public class Main{
//1 2 2 3 3
static int a[]= {2,1,2};
static int n = a.length;
static boolean st[] = new boolean[n];
static int [] f= new int[n];
public static void dfs(int u){
if( u == n){
for(int i = 0; i < n; i ++)
System.out.print(f[i]+" ");
System.out.println();
return;
}
for(int i = 0; i < n; i ++){
if( !st[i]){
//当前元素与前一个元素相同 且 前一个元素没有用过
if( i > 0 && a[i] == a[i - 1] && !st[i - 1]) continue;
st[i] = true;
f[u] = a[i];
dfs( u + 1);
st[i] = false;
}
}
}
public static void main(String args[]){
//Scanner reader = new Scanner(System.in);
//n = reader.nextInt();
Arrays.sort(a, 0, n);
dfs(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[] arr = new int[10002];//arr数组表示输入的序列
int[] dp = new int[10002];//dp数组中存放上升序列的长度,dp[i]表示以arr[i]结尾的子序列的最大长度
for(int i = 1;i <= n;i++) {//输入序列
int a = sc.nextInt();
arr[i] = a;
}
int result = -1;//记录dp中最大的值
for(int i = 1;i <= n;i++) {//按顺序计算dp[i]的值
dp[i] = 1;//假设该子序列中只有arr[i],故长度为1,即其自身成为一个子序列
for(int j = 1;j < i;j++) {
//如果在i之前有比arr[i]小的数(arr[j]),并且把该数(arr[i])放到以arr[j]结尾的子序列末尾后,
//其长度比当前以arr[i]结尾的子序列长度要长
if(arr[i] > arr[j] && dp[j] + 1 > dp[i]) {
dp[i] = dp[j] + 1;//把arr[i]放到以arr[j]结尾的子序列之后,原来的长度+1
}
}
result = Math.max(result, dp[i]);//找出在dp数组中最大的一个,即子序列长度最长的一个
}
System.out.println(result);
}
}