首页 > 编程语言 >第2章 基础算法

第2章 基础算法

时间:2024-08-01 17:07:12浏览次数:16  
标签:right Scanner int 基础 算法 static sc left

2.1 初级

(1)尺取法

⭐ 反向扫描(左右指针)

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		for( ; n > 0; n--) {
			char[] s = sc.next().toCharArray();
			boolean ans = true;
			int i = 0, j = s.length - 1;
			while(i < j) {
				if (s[i] != s[j]) {
					ans = false; break;
				}
				i++; j--;
			}
			System.out.println(ans ? "yes" : "no");
		}
	}
}

⭐ 同向扫描(快慢指针)

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int S = sc.nextInt();
		int[] a = new int[n];
		for(int i = 0; i < n; i++)
			a[i] = sc.nextInt();
		int left = 0, right = 0, val = 0, ans = n + 1;
		while (right < n) {
			while (val >= S) {
				ans = Math.min(ans, right - left);
				val -= a[left++];
			}
			val += a[right++];
		}
		System.out.println(ans == n + 1 ? 0 : ans);
		sc.close();
	}
}

(2)二分法

⭐ 整数二分
1 在单调递增序列中找左边 \(x\) 或 \(x\) 的后继(第一个大于 \(x\) 的数)

def binSearchBack(arr: List, x: int) -> int:
    # 当 x 大于所有值返回 N 故 right 赋值为 N
    left, right = 0, len(arr)
    while left < right:
        mid = (left + right) >> 1  # 左中位数
        if arr[mid] >= x:
            right = mid
        else:
            left = mid + 1
    return left

2 在单调递增序列中找右边 \(x\) 或 \(x\) 的前驱(最后一个小于 \(x\) 的数)

def binSearchFront(arr: List, x: int) -> int:
    # 当 x 小于所有值返回 -1 故 left 赋值为 -1
    left, right = -1, len(arr) - 1
    while left < right:
        mid = (left + right + 1) >> 1  # 右中位数
        if arr[mid] <= x:
            left = mid
        else:
            right = mid - 1
    return left
import java.util.Scanner;
import java.util.Arrays;

public class Main {
	static int N, C;
	static int[] x;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		N = sc.nextInt();
		C = sc.nextInt();
		x = new int[N];
		for(int i = 0; i < N; i++)
			x[i] = sc.nextInt();
		Arrays.sort(x);
		int left = 1, right = x[N - 1] - x[0];
		// 单调递减找左边第一个满足的值
		while(left < right) {
			// (3)由于左边不多移动 所以使用右中位数
			int mid = (left + right + 1) >> 1;
			if(check(mid))
				left = mid; // (1)满足条件 左边不多移动一格
			else
				right = mid - 1; // (2)不满足条件 右边需要多移动一格
		}
		System.out.println(left);
		sc.close();
	}

	static boolean check(int dis) {
		int cnt = 1, place = 0; // 第一个牛放第一个
		for(int i = 1; i < N; i++) {
			if(x[i] - x[place] >= dis) {
				cnt += 1; place = i;
			}
			if(cnt >= C) return true;
		}
		return false;
	}
}

⭐ 实数二分

import java.util.Scanner;

public class Main {
	static int T, N, F;
	static double eps = 1e-5;
	static double[] areas;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		T = sc.nextInt();
		for( ; T > 0; T--) {
			N = sc.nextInt(); F = sc.nextInt();
			areas = new double[N];
			double left = 0, right = 0;
			for(int i = 0; i < N; i++) {
				double r = sc.nextDouble();
				areas[i] = Math.PI * r * r;
				right = Math.max(right, areas[i]);
			}

			while(right - left > eps) {
				double mid = left + (right - left) / 2;
				if(check(mid))
					left = mid;
				else
					right = mid;
			}
			System.out.println(String.format("%.4f", left));
		}
	}

	static boolean check(double area) {
		int cnt = 0;
		for(int i = 0; i < N; i++) {
			cnt += (int)(areas[i] / area);
			if(cnt >= F + 1) return true;
		}
		return false;
	}
}

(3)三分法

⭐ 实数三分

import java.util.Scanner;

public class Main {
	static int N;
	static double eps = 1e-6;
	static double[] a;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		N = sc.nextInt(); a = new double[N + 1];
		double l = sc.nextDouble();
		double r = sc.nextDouble();
		for(int i = N; i >= 0; i--)
			a[i] = sc.nextDouble();
		while(r - l > eps) {
			double k = (r - l) / 3.0;
			double mid1 = l + k, mid2 = r - k;
			if(f(mid1) > f(mid2))
				r = mid2;
			else
				l = mid1;
		}
		System.out.println(String.format("%.5f", l));
	}

	static double f(double x) {
		double ans = 0;  // 多项式乘法
		for(int i = N; i >= 0; i--) 
			ans = ans * x + a[i];
		return ans;
	}
}

⭐ 整数三分

import java.util.Scanner;

public class Test {
	static long A, B, C, ans = Long.MAX_VALUE;
	static int n, m, tMin = Integer.MAX_VALUE;
	static int[] t, b;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		A = sc.nextLong(); B = sc.nextLong(); C = sc.nextLong();
		n = sc.nextInt(); m = sc.nextInt();
		t = new int[n]; b = new int[m];
		for(int i = 0; i < n; i++) {
			t[i] = sc.nextInt(); tMin = Math.min(tMin, t[i]);
		}
		for(int i = 0; i < m; i++) b[i] = sc.nextInt();

		if(C >= 1e16) {  // 有特例需要特判 否则导致数字过大
			// 由于 C 过大 故所有科目均须在最小期望天数之前公布
			ans = calc1(tMin);
		} else {
			// 不愉快度是时间的下凹函数 采取整数三分策略
			int L = 1, R = 100000;
			while(R - L > 2) {
				int mid1 = L + (R - L) / 3, mid2 = R - (R - L) / 3;
				long c1 = calc1(mid1) + calc2(mid1);  // c1 总不满意度
				long c2 = calc1(mid2) + calc2(mid2);  // c2 总不满意度
				if(c1 > c2) L = mid1;
				else R = mid2;
			}
			for(int i = L; i <= R; i++)  // 寻找此区间的最小值
				ans = Math.min(ans, calc1(i) + calc2(i));
		}
		System.out.println(ans);
	}

	static long calc1(int time) { // 所有科目在 time 之前公布的不满意度
		// 不满意度来自操作1 和 操作2
		long x = 0, y = 0;  // x 记录需增加天数 y 记录需减少天数
		for(int i = 0; i < m; i++) {
			if(b[i] > time) y += b[i] - time;
			else x += time - b[i];
		}
		if(A < B) { // 由于操作1 会导致 +1 和 -1 故最大操作次数为 min(x, y)
			// 增加的天数可以不增加 减少的天数必须减少 故剩余天数使用操作二执行
			return Math.min(x, y) * A + (y - Math.min(x, y)) * B;
		} else { // 如果操作2 的花费小于操作1 的花费 只需使用操作2
			return y * B;  // 只需将超过 time 的科目变为 time 即可
		}
	}

	static long calc2(int time) { // 所有科目在 time 之前公布学生的不满意度
		long sum = 0;
		for(int i = 0; i < n; i++)
			sum += time > t[i] ? (time - t[i]) * C : 0;
		return sum;
	}
}

(4)排序与排列

⭐ 排序

import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class Test {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();
		int[][] stus = new int[N][5];
		for(int i = 0; i < N; i++) {
			stus[i][0] = i + 1; stus[i][1] = sc.nextInt();
			stus[i][2] = sc.nextInt(); stus[i][3] = sc.nextInt();
			stus[i][4] = stus[i][1] + stus[i][2] + stus[i][3];
		}
		Arrays.sort(stus, Comparator.comparingInt(
				(int[] stu) -> -stu[4]).thenComparingInt(
						stu -> -stu[1]).thenComparingInt(
						stu -> stu[0]));
		for(int i = 0; i < 5; i++) {
			System.out.println(stus[i][0] + " " + stus[i][4]);
		}
	}
}

⭐ 排列

public class Main {
	static boolean[] vis = new boolean[14];
	static int[] b = new int[14];
	static int ans;
	public static void main(String[] args) {
		dfs(1); // 从第一个空开始填写数字
		System.out.println(ans);
	}

	static void dfs(int cur) {
		if(cur == 13) {
			if(b[10] * b[11] == b[12])
				ans++;
			return;
		}

		if(cur == 4 && b[1] + b[2] != b[3]) return;
		if(cur == 7 && b[4] - b[5] != b[6]) return;
		if(cur == 10 && b[7] * b[8] != b[9]) return;

		for(int i = 1; i <= 13; i++) {
			if(!vis[i]) {
				vis[i] = true;
				b[cur] = i; dfs(cur + 1);
				vis[i] = false;
			}
		}
	}
}

2.2 中级

(1)倍增法与ST算法

(2)前缀和与差分

(3)离散化

(4)分治法

(5)贪心法与拟阵

标签:right,Scanner,int,基础,算法,static,sc,left
From: https://www.cnblogs.com/XuGui/p/18337038

相关文章

  • 论文阅读:高效的广义最稠密子图发现算法
    摘要这篇论文提出了一种高效算法,通过利用广义超模密度定义和......
  • 机器学习-算法分类以及用途
    1.监督学习算法线性回归(LinearRegression)目的:用于预测一个或多个自变量(X)与因变量(Y)之间的线性关系。应用领域:房价预测、销售预测、温度预测等连续值预测问题。逻辑回归(LogisticRegression)目的:虽然名为回归,但实际上是用于二分类问题的分类算法。应用领域:垃圾邮件识别、......
  • prim算法求最小生成树
    prim算法求最小生成树#include<bits/stdc++.h>usingnamespacestd;constintN=600;intg[N][N];//n的平方约等于m,所以用邻接矩阵,存放权值。g[i][j]表示边ij的长度为g[i][j]constintinf=0x3f3f3f3f;//无穷大0x3f3f3f3fintdist[N];//该点到集合里点的最小值boolst[N]......
  • 克鲁斯卡尔算法
    克鲁斯卡尔算法稀疏图-->用克鲁斯卡尔算法克鲁斯卡尔算法套路:首先存放每条边用struct然后按照权值从小到大排序然后如果这条边的两个端点已经在一个连通块就不要把这条边放进来(因为生成树不能有闭合回路)如已经有边12,边13不能再放入边23判断连通块用find函数利用并查集算法......
  • iOS开发基础145-Apple Search Ads
    AdServices框架是Apple引入的一种用于衡量广告效果的工具,特别是针对应用安装广告(AppInstallAds)的归因。它有助于广告主和广告平台了解他们的广告是否成功引导了用户下载和安装应用。使用AdServices集成在iOS应用中,一般目标是获得与广告相关的追踪参数,如广告活动(Campaign)、广......
  • 刀具磨损预测工器具磨损预测-RIME-CNN-SVM霜冰算法优化-完整代码数据
    直接看项目演示:刀具磨损预测工器具磨损预测-RIME-CNN-SVM霜冰算法优化_哔哩哔哩_bilibili效果演示:代码: importnumpyasnpimporttorchimporttorch.nnasnnimporttorch.nn.functionalasFimporttorch.optimasoptimfromtorch.utils.dataimportDataLoad......
  • 代码随想录算法训练营第56天 | 广搜和深搜应用
    110.字符串接龙https://kamacoder.com/problempage.php?pid=1183代码随想录https://www.programmercarl.com/kamacoder/0110.字符串接龙.html#思路105.有向图的完全可达性https://kamacoder.com/problempage.php?pid=1177代码随想录https://www.programmercarl.com/kamaco......
  • Web专项——基础题目
    注:web_基础题目以bugku练习题目为例!第一部分web_1_Simple_SSTI_1(1)思路:启动场景网页显示Youneedpassinaparameternamedflag。//你需要传入一个名为flag的参数查看源码发现Youknow,intheflask,Weoftensetasecret_keyvariable.就是提示你用flask模板进行注入......
  • Day 30 贪心算法 Part04
    452.用最少数量的箭引爆气球自己写没写出来,不过找到篇很好的题解,贪心想不到就是想不到,没办法。本以为自己的思路也是贪心,但就是做不出来。classSolution{publicintfindMinArrowShots(int[][]points){boolean[]visited=newboolean[points.length];......
  • 计算机基础(Windows 10+Office 2016)教程 —— 第5章 文档编辑软件Word 2016(上)
    文档编辑软件Word20165.1Word2016入门5.1.1Word2016简介5.1.2Word2016的启动5.1.3Word2016的窗口组成5.1.4Word2016的视图方式5.1.5Word2016的文档操作5.1.6Word2016的退出5.2Word2016的文本编辑5.2.1输入文本5.2.3插入与删除文本5.2.4复制与......