注意:以下部分内容摘自Acwing,仅用于个人学习记录,不做任何商业用途。
(1)快速排序
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main{
public static void main(String[] args) throws IOException{
InputStreamReader in = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(in);
int num = Integer.parseInt(br.readLine());
int[] arr = new int[num];
String[] res = br.readLine().split(" ");
for (int i = 0; i < num; i++) {
arr[i] = Integer.parseInt(res[i]);
}
quickSort(arr, 0, num - 1);
for (int i = 0; i < num; i++) {
System.out.print(arr[i] + " ");
}
br.close();
}
//快排模板 v.v
public static void quickSort(int[] q, int l, int r) {
if (l >= r) return;
int x = q[l+r>>1];
//Define positions of two pointers
int i = l - 1;
int j = r + 1;
while (i < j) {
do i++; while (q[i] < x);
do j--; while (q[j] > x);
//do Swap
if (i < j) {
int temp = q[i];
q[i] = q[j];
q[j] = temp;
}
}
quickSort(q, l, j);
quickSort(q, j + 1, r);
}
}
(2)归并排序
public class Main {
public static void main(String[] args) {
// 对输入值进行初始化
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = in.nextInt();
}
// 归并排序
merge_sort(arr, 0, n - 1);
// 打印输出
for (int i = 0; i < n; i++)
System.out.print(arr[i] + " ");
}
// 归并排序
private static void merge_sort(int[] arr, int l, int r) {
// 递归结束条件
if (l >= r) return;
// 以下都为逻辑部分
int mid = l + r >> 1;
merge_sort(arr, l, mid);
merge_sort(arr, mid + 1, r);
int[] tmp = new int[r - l + 1]; // 临时数组, 用于临时存储 [l,r]区间内排好序的数据
int i = l, j = mid + 1, k = 0; // 两个指针
// 进行归并
while (i <= mid && j <= r) {
if (arr[i] <= arr[j])
tmp[k++] = arr[i++];
else
tmp[k++] = arr[j++];
}
while (i <= mid) tmp[k++] = arr[i++];
while (j <= r) tmp[k++] = arr[j++];
// 进行赋值
for (i = l, j = 0; i <= r; i++, j++)
arr[i] = tmp[j];
}
}
(3)二分
// 区间[l, r]被划分成 [l, mid] 和 [mid+1, r]时使用
int bsearch_1(int l, int r) {
while (l < r) {
int mid = l + r >> 1;
if (check[mid) // check() 判断 mid是否满足性质
r = mid;
else
l = mid + 1;
}
return l;
}
// 区间[l, r]被划分成 [l, mid-1] 和 [mid, r]时使用
int bsearch_2(int l, int r) {
while (l < r) {
int mid = l + r + 1 >> 2; // 注意
if (check[mid) // check() 判断 mid是否满足性质
l = mid;
else
r = mid - 1;
}
return l;
}
(4)高精度加减乘除(JAVA)
import java.io.*;
import java.math.BigInteger;
public class Main {
public static void main(String[] args) throws IOException{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
BigInteger a = new BigInteger(reader.readLine());
BigInteger b = new BigInteger(reader.readLine());
//add
System.out.println(a.add(b));
//减法 subtract( )
System.out.println(a.subtract(b));
//乘法 multiply( )
System.out.println(a.multiply(b));
//divide 返回值为 a/b
BigInteger[] c = a.divideAndRemainder(b); //返回值为数组,分别为a/b和a%b
System.out.println(c[0]);
System.out.println(c[1]);
//取余 mod( )
System.out.println(a.mod(b));
reader.close();
}
}
以下是小数模版
BigDecimal(char[] in)
一个转换的字符数组表示 BigDecimal成 BigDecimal ,接受字符作为的相同序列 BigDecimal(String)构造。
BigDecimal(char[] in, int offset, int len)
一个转换的字符数组表示 BigDecimal成 BigDecimal ,接受字符作为的相同序列 BigDecimal(String)构造,同时允许一个子阵列被指定。
BigDecimal(double val)
将 double转换为 BigDecimal ,这是 double的二进制浮点值的精确十进制表示
BigDecimal(int val)
将 int成 BigDecimal
BigDecimal(long val)
将 long成 BigDecimal
BigDecimal(String val)
import java.io.*;
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
BigDecimal a = new BigDecimal(reader.readLine());
BigDecimal b = new BigDecimal(reader.readLine());
//加法
System.out.println(a.add(b));
//其余同上
reader.close();
}
}
(5)高精度加减乘除(C++)
(1)加法:
算法思路:
计算 567 + 28
用 a, b 两个字符串存储输入。a = 567, b = 28
为了方便计算,将两个数分别 倒序 存放在 A, B 两个整数数组中。 A = [7, 6, 5], B = [8, 2]
新建整数数组 C 保存结果,整型变量 t 保存进位,初始 t = 0.
将各个位上的数字相加,求出结果对应位上的数字和进位。
例如对个位计算: A[0] + B[0] = 7 + 8 = 15, 结果个位上是 5, 进位是 1. 所以 C[0] = 5, 进位 t = 1
最后把结果数组 C 中就保存了计算倒序结果,倒序输出就是答案
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(new BufferedInputStream(System.in));
String a = scanner.next();
String b = scanner.next();
int aLength = a.length() - 1;
int bLength = b.length() - 1;
List<Integer> list = new ArrayList<>((int)(1e6+10));
int carry = 0;
int max = Math.max(aLength,bLength) + 1;
while (max --> 0 ){
int x = aLength < 0 ? 0 : a.charAt(aLength) - '0';
int y = bLength < 0 ? 0 : b.charAt(bLength) - '0';
int sum = x + y + carry;
list.add(sum % 10);
carry = sum / 10;
aLength--;
bLength--;
}
if (carry != 0) list.add(1);
for (int i = list.size() - 1; i >= 0; i--){
System.out.print(list.get(i));
}
}
}
作者:byteflow666
链接:https://www.acwing.com/solution/content/139804/
来源:AcWing
(2)减法:
算法思路:
(模拟数从后向前减)
初始化借位t = 0
计算加法t = a - b - t 其中a, b范围为(0,9), t为借位0 or 1,同时临时用来存储减法的结果
计算结果值 (t + 10)% 10 如果t为负的,比如-1,向前借一位,(10 - 1) = 9
如果t为正的,比如1,无需向前借一位,(10 + 1) % 10 = 1
计算借位值,用于下次计算 t = 0 or 1 如果t为负的,表示需要向前借一位(正好印证前面借位), t = 1
如果t为正的,无需向前借一位,t = 0
import java.util.Scanner;
public class Main{
public static void main(String[] args){
String a, b;
Scanner sc = new Scanner(System.in);
a = sc.next();
b = sc.next();
char[] A = new char[a.length()], B = new char[b.length()];
for(int i = a.length() - 1; i >= 0; i --) A[a.length() - 1 - i] = a.charAt(i);
for(int i = b.length() - 1; i >= 0; i --) B[b.length() - 1 - i] = b.charAt(i);
if(cmp(A, B)){
String c = sub(A, B);
System.out.println(c);
}else{
String c = sub(B, A);
System.out.print("-");
System.out.println(c);
}
}
public static String sub(char[] A, char[] B){
StringBuffer sb = new StringBuffer();
int t = 0;
for(int i = 0; i < A.length; i ++){
t = A[i] - '0' - t; //注意要减去-'0'
if(i < B.length) t -= B[i] - '0';
sb.append((t + 10) % 10);
if(t < 0) t = 1;
else t = 0;
}
String s = sb.reverse().toString();
int i = 0;
for(; i < s.length() - 1; i ++)
if(s.charAt(i) != '0') break;
return s.substring(i, s.length());
// char[] C = sb.reverse().toString().toCharArray();
// //针对77 - 70 = 07 => 7 77 - 77 = 00 => 0
// //利用截取,来去除开头的0, 当全为0的时候保留1位0
// int i = 0; //记录开头位置不为0
// for(; i < C.length - 1; i ++)
// if(C[i] != '0') break;
// return new String(C).substring(i, C.length);
}
public static boolean cmp(char[] A, char[] B){
if(A.length != B.length) return A.length > B.length;
//相等从高位进行比较
for(int i = A.length - 1; i >= 0; i --){
if(A[i] != B[i]) return A[i] > B[i];
}
return true;
}
}
作者:派大星的梦想
链接:https://www.acwing.com/solution/content/32440/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
(3)乘法
AcWing 793. 高精度乘法 A x b 和 A x B 的模版(大数相加、大数相乘通用模板) - AcWing
(4)除法
思路:
数组A[]: 1 2 6
数b 25
模拟过程
初始化余数r = 0
((r = 0) * 10 + (A[0] = 1)) / 25 = 0 ... r = 1
((r = 1) * 10 + (A[1] = 2)) / 25 = 0 ... r = 12
((r = 12) * 10 + (A[2] = 2)) / 25 = 5 ... r = 1
A遍历完,得到商和余数
初始化余数r = 0
计算乘法r = r * 10 + A[i] 其中A[i]为数组中的第i个数, b为数, r用来存储当前的结果
计算结果值 r / 10
计算余数,用于下次计算 r = r / 10
import java.util.Scanner;
public class Main{
static int r;
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String a = sc.next();
int b = sc.nextInt();
char[] A = new char[a.length()];
for(int i = a.length() - 1; i >= 0; i --) A[a.length() - 1 - i] = a.charAt(i);
String res = div(A, b);
System.out.println(res);
System.out.println(r);
}
public static String div(char[] A, int b){
StringBuffer sb = new StringBuffer();
r = 0;
for(int i = A.length - 1; i >= 0; i --){
r = r * 10 + A[i] - '0';
sb.append(r / b);
r %= b;
}
String s = sb.toString();
int i = 0;
for(; i < s.length()- 1; i++){
if(s.charAt(i) != '0') break;
}
return s.substring(i, s.length());
}
}
作者:派大星的梦想
链接:https://www.acwing.com/solution/content/32448/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
(6)前缀和
import java.io.IOException;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException{
Scanner in=new Scanner(System.in);
int n=in.nextInt();
int m=in.nextInt();
int q=in.nextInt();
int [][] arr=new int [n+1][m+1];
//输入
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
arr[i][j]=in.nextInt();
//前缀和s数组
int [][] s=new int [n+1][m+1];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+arr[i][j];
//输出
while (q-- > 0) {
// 定位获取区间大小
int x1 = in.nextInt();
int y1 = in.nextInt();
int x2 = in.nextInt();
int y2 = in.nextInt();
// 计算, 结合图来理解
int res = s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1];
System.out.println(res);
}
}
}
图解如下:
(7)差分
package 差分;
import java.io.*;
public class Main {
static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter log = new BufferedWriter(new OutputStreamWriter(System.out));
static int N = 100010;
static int[] b = new int[N];
static int[] arr = new int[N];
public static void main(String[] args) throws IOException {
String[] s = reader.readLine().split(" ");
int n = Integer.parseInt(s[0]);
int m = Integer.parseInt(s[1]);
String[] sArr = reader.readLine().split(" ");
for (int i = 1; i <= n; i++) {
arr[i] = Integer.parseInt(sArr[ i - 1 ]);
b[i] = arr[i] - arr[i - 1];
}
while(m -- > 0){
String[] in = reader.readLine().split(" ");
int l = Integer.parseInt(in[0]), r = Integer.parseInt(in[1]), val = Integer.parseInt(in[2]);
b[l] += val;
b[r + 1] -= val;
}
for (int i = 1; i <= n; i++) {
arr[i] = arr[i - 1] + b[i];
log.write(arr[i] + " ");
}
reader.close();
log.flush();
log.close();
}
}
(8)双指针
最长不重复子序列
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int n=Integer.parseInt(br.readLine());
String[] s=br.readLine().split(" ");
int[] arr=new int[n];
for(int i=0;i<n;i++)
arr[i]=Integer.parseInt(s[i]);
int[] a=new int[100010];
int res=0;
int left=0;//左端点
for(int i=0;i<n;i++) {
a[arr[i]]++;
while(left<i&&a[arr[i]]>1) {
a[arr[left]]--;
left++;
}
if(res<i-left+1)res=i-left+1;
}
System.out.print(res);
}
}
(9)二进制中1的个数
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
while(n -- != 0){
int x = sc.nextInt();
int res = 0;
while(x != 0){
x -= lowbit(x);
res ++;
}
System.out.print(res + " ");
}
}
public static int lowbit(int x){
return x & -x;
}
}