printf()输出格式小tips

#include<stdio.h>
#include<string.h>
int main()
{ char c, s[20]; int a=1234;float f=3.141592653589; double x=0.12345678912345678; strcpy(s, "Hello,World"); c='\x41'; printf("a=%d\n", a);//按照十进制整数格式输出,显示 a=1234printf("a=%d%%\n", a);//输出%号 结果 a=1234%printf("a=%6d\n", a);//输出6位十进制整数 左边补空格,显示 a= 1234printf("a=%06d\n", a);//输出6位十进制整数 左边补0,显示 a=001234printf("a=%2d\n", a);//a超过2位,按实际输出 a=1234printf("a=%-6d\n", a);///输出6位十进制整数 右边补空格,显示 a=1234printf("f=%f\n", f);//浮点数有效数字是7位,结果 f=3.141593printf("f=%6.4f\n", f);//输出6列,小数点后4位,结果 f=3.1416printf("x=%lf\n", x);//输出长浮点数 x=0.123457printf("x=%18.16lf\n", x);//输出18列,小数点后16位,x=0.1234567891234567printf("c=%c\n", c);     //输出字符 c=Aprintf("c=%x\n", c);//以十六进制输出字符的ASCII码 c=41printf("s[]=%s\n", s);//输出数组字符串s[]=Hello,Worldprintf("s[]=%6.9s\n", s);//输出最多9个字符的字符串 s[]=Hello,Worreturn 0;
}

排序


冒泡排序

int a[];
for(int i=0;i<a.length-1;i++)
{   //一轮过后已经选出最大的一个并排好,所以要-ifor(int j=0;j<a.length-1-i;j++){if(a[j]>a[j+1])//从小到大排序{int temp=a[j];a[j]=a[j+1];a[j+1]=temp;}}
}
//最坏情况下,时间复杂度为O{n(n-1)/2}

*快排

基于分治

1.确定分界点

2.调整区间

3.递归

//快排 2.0
public static void quicksort(int[] arr, int left, int right) {if (left > right) {return;}int base = arr[(left + right) / 2];//确定分界点int i = left;int j = right;while (i <= j) {while (arr[j] > base) {j--;}while (arr[i] < base) {i++;}if (i <= j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;j--;i++;}}quicksort(arr, left, j);quicksort(arr, i, right);}
//快排进阶,在乱序数组中找到排好序后的第几个数,时间大大优化
public static void quicksort(int[] arr, int left, int right, int k) {if (left == right) {System.out.println(arr[left]);return;}int base = arr[(left + right) / 2];int i = left;int j = right;while (i <= j) {while (arr[j] > base) {j--;}while (arr[i] < base) {i++;}if (i <= j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;i++;j--;}}if (k <= j) {quicksort(arr, left, j, k);} else if (i <= k) {quicksort(arr, i, right, k);} else {quicksort(arr, j + 1, i - 1, k);}}

*归并排序

基于分治

1.确定分界点:mid=(left+right)/2

2.递归排序left,right

3.归并 --合二为一

private static void merge_sort(int arr[], int left, int right) {if (left >= right) {return;}int mid = (left + right) / 2;merge_sort(arr, left, mid);merge_sort(arr, mid + 1, right);int k = 0, i = left, j = mid + 1;while (i <= mid && j <= right) {if (arr[i] <= arr[j]) {temp[k++] = arr[i++];} else {temp[k++] = arr[j++];}}while (i <= mid) {temp[k++] = arr[i++];}while (j <= right) {temp[k++] = arr[j++];}for (i = left, j = 0; i <= right; i++, j++) {arr[i] = temp[j];}}

堆排序

import java.util.Arrays;
import java.util.Scanner;public class 堆排序 {static int n;private static void heapSort(int[] arr) {for (int end = n - 1; end > 0; end--) {maxheap(arr, end);int temp = arr[0];arr[0] = arr[end];arr[end] = temp;}}private static void maxheap(int[] arr, int end) {int lastfa = (0 + end) % 2 == 0 ? (0 + end) / 2 - 1 : (0 + end) / 2;for (int fa = lastfa; fa >= 0; fa--) {int left = fa * 2 + 1;int right = fa * 2 + 2;if (right <= end && arr[right] > arr[fa]) {int temp = arr[right];arr[right] = arr[fa];arr[fa] = temp;}if (arr[left] > arr[fa]) {int temp = arr[left];arr[left] = arr[fa];arr[fa] = temp;}}}public static void main(String[] args) {Scanner sc = new Scanner(System.in);n = sc.nextInt();int arr[] = new int[n];for (int i = 0; i < n; i++) {arr[i] = sc.nextInt();}heapSort(arr);System.out.println(Arrays.toString(arr));}}

二分


整数二分

1.找中间值 mid=(l+r)/2

//区间[l,r]被划分为[l,mid]和[mid+1,r]时使用:
int bsearch_1(int l,int r){while(l<r){int mid=(l+r)/2;if(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)){l=mid;}else{r=mid-1;}}return l;
}

浮点数二分

//浮点数没有加一减一的问题,所以相对整数二分简单一些
//当范围小于1e-6时认为是解,如要求保留几位小数,则4位—》1e-6,5位-》1e-7
例:求一个数的平方根double x;
double l=0,r=x;
while(r-l>1e-6){double mid=(l+r)/2;if(mid*mid>=x){r=mid;}else{l=mid;}
}

java快读和快输模板



import java.io.*;
public class Main {private static StreamTokenizer st;                //构建快读模块private static int nextInt()throws IOException{st.nextToken();return (int)st.nval;}public static void main(String[] args) throws IOException{st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));//初始化 StreamTokenizerint N = nextInt(), M = nextInt();//变量N和M使用快读构造方法,构建;int tmp;int val[] = new int[N+1];for (int i=1;i<=M;i++) val[nextInt()]++;PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));//构建快输模块for (int i=1;i<=N;i++) {while(val[i]!=0)  {pw.print(i+" ");val[i]--;}}pw.close();//关闭,如果还要用,则改为pw.f}
}

判断数字是否为回文数

 int s = i, num = 0;while (s != 0) {num = num * 10 + s % 10;s /= 10;}

快输,快读(BufferedReader)

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String s = in.read() // 读入一个字符 可读入空格回车 但不抛弃回车
String s1 = in.readLine(); // 读入一行 可读入空格可读入回车 但会将回车抛弃
string s2[] = in.readLine().Split(" "); // 使用Split通过空格分割读入的一行字符串,存在s2中
//输入整数51 3 2 5 6
int N = Integer.valueOf(in.readLine());int arr[] = new int[n];String s = in.readLine();String s2[] = s.split(" ");for (int i = 0; i < N; i++) {arr[i] = Integer.parseInt(s2[i]);}
//输入:5c d a bb ereader.readLine()//读入第一行的数字String str = reader.readLine();//读入第二行的字母String[] s = str.split(" ");//把第二行的空格切走Arrays.sort(s);//对切完后的字符串排序StringBuilder sb = new StringBuilder();//把最后结果放在这里面for(String st : s){sb.append(st);sb.append(" ");}BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
主要使用 BufferedWriter类中的 write() 类进行输出。 当数据量大的时候一定要使用这个类进行输出,谨记!需要注意的是 write() 不能直接输出int类型, 因为write(int a)  会输出其对应的ASCii码的字符 ,比如输出 65 会显示 A 详见代码:int a = 65;
char b = '2';
String c = "3";out.write(a);
out.write("\n");
out.write(b);
out.write("\n");
out.write(c);
out.write("\n");
out.flush();输出:
A
2
3所以当需要输出一个int类型的变量时, 可以用Integer.toString(int a)方法 将其变为字符串形式输出。或者使用 + 拼接一个字符串,这样 参数整体就是一个字符串了,比如加一个换行符。详见代码:int a = 65;out.write(a + "\n");
out.write(Integer.toString(a));
out.flush();输出:
65
65//这里要注意在使用out输出之后,如果要换行,不能用System.out.println(),只能用out.writer("\n");来换行
————————————————
版权声明:本文为CSDN博主「Androids_lost_Sheep」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/GD_ONE/article/details/103480407

汉诺塔游戏(递归)

目的:A->B

过程:A->C,C->B=>A->B;

import java.util.Scanner;public class 汉诺塔游戏 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();printHanoitower(n, "A", "B", "C");}static void printHanoitower(int n, String from, String to, String help) {if (n == 1) {System.out.println("move" + n + "from" + from + "to" + to);} else {printHanoitower(n - 1, from, help, to);System.out.println("move" + n + "from" + from + "to" + to);printHanoitower(n - 1, help, to, from);}}}

重写compareto()自定义比较基准来进行排序

class job implements Comparable<job> {//构建工作对象int s;int t;public job(int s, int t) {this.s = s;this.t = t;}public int compareTo(job other) {//由于要以工作对象的结束时间作为比较排序的基准,这里需要对comparable//里的comparaTo函数进行重载//int compareTo(T t)方法说明 //定义:比较此对象与指定对象的顺序。//返回:负整数、零或正整数。如果该对象小于、等于或大于指定对象,则//分别返回负整数、零或正整数。//假如result返回1。Collections.sort(List)方法就是升序;//假如result返回-1。Collections.sort(List)方法就是降序;int x = this.t - other.t;if (x == 0) {return this.s - other.s;} else {return x;}}}

java高精度模板题

Input

T输入包括多组 R 和 n。 R 的值占第 1 到第 6 列,n 的值占第 8 和第 9 列。

Output

对于每组输入,要求输出一行,该行包含精确的 R 的 n 次方。输出需要去掉前导的 0 后不要的 0 。如果输出是整数,不要输出小数点。

Sample Input

95.123 12
0.4321 20
5.1234 15
6.7592  9
98.999 10
1.0100 12

Sample Output

548815620517731830194541.899025343415715973535967221869852721
.00000005148554641076956121994511276767154838481760200726351203835429763013462401
43992025569.928573701266488041146654993318703707511666295476720493953024
29448126.764121021618164430206909037173276672
90429072743629540498.107596019456651774561044010001
1.126825030131969720661201
import java.math.BigDecimal;
import java.util.Scanner;public class Main {public static void main(String args[]) {Scanner sc=new Scanner(System.in);while(sc.hasNext()) { //判断有无下一个输入数据BigDecimal x=sc.nextBigDecimal();int n=sc.nextInt();BigDecimal ans=BigDecimal.ONE;for(int i=0;i<n;i++) {ans=ans.multiply(x);//BigDecimal的乘法需要调用multiply()方法,乘以一个BigDecimal对象,返回一个BigDecimal对象}String s=ans.toPlainString();//在这里要使用toPlainString()方法,默认的toString()方法在某些情况是科学计数法,错了很多次才知道/** 例如样例:* 0.000001 5 */int len=s.length();int leadzero=-1;boolean metdot=false;for(int i=0;i<len;i++) {if(leadzero==-1&&s.charAt(i)!='0') {leadzero=i;//把整数部分的0去掉}if(s.charAt(i)=='.') {metdot=true;//遇到了小数点,说明是小数break;}}if(metdot==true) {s=s.substring(leadzero);//遇到了小数点,说明是小数len=s.length();//重新计算s的长度,因为前面可能截断了整数部分的0int releadzero=-1;for(int i=len-1;i>=0;i--) {if(s.charAt(i)!='0') {releadzero=i+1;//遇到第一个非零位置,其后的无效0截断if(s.charAt(i)=='.') {releadzero=i;//遇到第一个非零位置是小数点,连小数点也截断}break;}}s=s.substring(0,releadzero);}else {//没有遇到小数点,是整数,不可能有无效0;}System.out.println(s);}sc.close();}
}

重写Arrays.sort()实现从大到小排序

package com.itheimajavase;import java.util.Arrays;
import java.util.Comparator;public class Day01 {public static void main(String[] args) {Integer[] arr = {4, 6, 3, 9, 1, 5, 8};Mycomparator c = new Mycomparator();    // 实例化一个Comparator对象Arrays.sort(arr, c);for(Integer ele : arr) {System.out.print(ele +" ");}}// 运行后是从大到小排好序的
}
class Mycomparator implements Comparator<Integer> {@Overridepublic int compare(Integer o1, Integer o2) {if(o1 > o2) // 默认是o1 < o2时返回-1, 一下同理return -1;if(o1 < o2)return 1;return 0;}
}

进制问题

1<<16==2的16次方

1e6+10=1000010

方块数学小tip

一块长n,宽m的巧克力,能分成边长为x的正方形巧克力s块?s块为多少

公式:s=(n/x)*(m/x)

前缀合tips

一维数组:

//求l到r的和
s[i]=s[i-1]+arr[i]; //初始化前缀和数组
res=s[r]-s[l-1];//二维前缀和
//利用前缀和
s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+arr[i][j];//初始化
左上点坐标 x1,y1   右上点坐标  x2,y2
//求子矩阵的和sum=s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y]//三维前缀和

数论

质数判定

质数判定(试除法)

check(i){  //判断是否为质数,时间复杂度O(sqrt(n))for(int i=2;i<=n/i;i++){if(n%i==0){return false;}
}
return true
}

分解质因数(试除法)

//时间复杂度O(sqrt(n))import java.util.Scanner;public class 质因数分解 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();gcd(n);}static void gcd(int n) {for (int i = 2; i <= n / i; i++) {if (n % i == 0) {int s = 0;while (n % i == 0) {n /= i;s++;}System.out.println(i + " " + s);}}if (n > 1) {System.out.println(n + " " + 1);}}
}

质数筛

//埃式筛法,时间复杂度 O(nloglogn)import java.util.Scanner;public class 筛质数 {static int N = 1000010;static int primes[] = new int[N];static boolean st[] = new boolean[N];static int cnt = 0;public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();get_primes(n);for (int i = 0; i < cnt; i++) {System.out.println(primes[i]);}sc.close();}static void get_primes(int n) {for (int i = 2; i <= n; i++) {if (!st[i]) {primes[cnt++] = i;for (int j = 2 * i; j <= n; j += i) {st[j] = true;}}}}
}//线性筛法
时间复杂度 O(n)
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.ArrayList;public class 线性筛质数 {static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));static int nextInt() throws IOException {in.nextToken();return (int) in.nval;}static ArrayList<Integer> primes = new ArrayList<>();static boolean st[];static int cnt = 0;public static void main(String[] args) throws IOException {int n = nextInt();int m = nextInt();st = new boolean[n + 1];get_primes(n);while (m-- > 0) {int e = nextInt();out.write(primes.get(e - 1) + "\n");}out.flush();}static void get_primes(int n) {for (int i = 2; i <= n; i++) {if (!st[i]) {primes.add(i);}for (int j = 0; j < primes.size(); j++) {if (primes.get(j) * i > n) {break;}st[primes.get(j) * i] = true;if (i % primes.get(j) == 0) {break;}}}}}

求约数

// 1、试除法求一个数所有的约数

求最大公约数

欧几里得算法(辗转相除法)

public static int gcd(int m,int n){return n==0?m:gcd(n,m%n)
}

裴蜀定理

扩展欧几里得算法

void exgcd(int a,int b,long x,long y){if(b==0){x.v=1;y.v=0;return a;}long d= exgcd(b,a%b,y,x);y.v-=(a/b)*(x.v);return d
}class Long{long v;public Long(long v){this.v=v;}
}

赛瓦维斯特定理

a,b>1,ab的最大公约数=1(互素),使得ax+by=c,无正整数解的c最大为,c=ab−a−ba,b>1,ab的最大公约数=1(互素),使得 ax+by=c,无正整数解的c最大为,c=ab-a-b a,b>1,ab的最大公约数=1(互素),使得ax+by=c,无正整数解的c最大为,c=ab−a−b

算术基本定理

所有正整数是一定可以唯一的分成为若干个质因子相乘

小tips

1.已知两个互质的数a和b,则这两个数最大不能组成的数为a*b-a-b;

2.求数的上取整:a/b=(a+b-1)/b(a/b上取整)

3.s-v除以n的结果x如果要求为n的倍数,则改式可以转换为,s%n的余数等于v%n的余数

4.(同余式)(a+b)%n=j等价于(a+b)=j(%n);同时一边的数可以加到另一边,符号改变即可–>a=j-b(%n);

判断闰年

5.1 年份能被4整除,但不能被100整除;

5.2 年份能被400整除;

year%100!=0&&year%4==0||year%400==0;

6.防止出现负余数: (a%b+b)%b

6.等差数列前n项和:前n项和公式为:Sn=n*a1+n(n-1)d/2或Sn=n(a1+an)/2

均值不等式

扩展欧几里得算法

此算法求 已知a和b,ax+by=(a和b的最大公约数)的x和y

import java.util.Scanner;public class test {static long x;static long y;public static void main(String[] args) {Scanner scanner = new Scanner(System.in);try {linearEquation(2, 7, 1);System.out.println(x + " " + y);} catch (Exception e) {// TODO Auto-generated catch blockSystem.out.println("无解");}}public static long ext_gcd(long a, long b) {if (b == 0) {x = 1;y = 0;return a;}long res = ext_gcd(b, a % b);long x1 = x;x = y;y = x1 - a / b * y;return res;}public static long linearEquation(long a, long b, long m) throws Exception {long d = ext_gcd(a, b);if (m % d != 0)throw new Exception("无解");long n = m / d;x *= n;y *= n;return d;}
}

DP问题

闫氏DP分析法

从集合角度分析DP问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v9rsF0z3-1653210209939)(D:\桌面\笔记学习\images\闫氏dp.png)]

​ (01背包问题为例)

树状数组

时间复杂度:Olog(n)

用法:

1.单点修改

2.区间查询

树状数组下标必须从1开始

//树状数组的三个基本操作
int a[];  //原数组
int tr[];  //树状数组
int lowbit(int x){return x&-x;
}
void add(int x,int v){  //单点修改for(int i=x;i<=n;i+=lowbit(i)){t[i]+=v;}
}void query(int x){  //区间查询前缀和int res=0;for(int i=x;i;i-=lowbit(i)){res+=tr[i];}
}

差分

差分是前缀和的逆运算

给定a[1],a[2],a[3],a[n]

构造差分数组b[N],使得a[i]=b[1]+b[2]+…b[i];

核心操作:将,a[l~r]全部加上c,等价于b[l]+=c,b[r+1]-=c

//一维差分
public class 拆分 {static int N = 100010;static int a[] = new int[N];static int b[] = new int[N];public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();int m = sc.nextInt();for (int i = 1; i <= n; i++) {a[i] = sc.nextInt();add(i, i, a[i]);}for (int i = 1; i <= m; i++) {int l = sc.nextInt();int r = sc.nextInt();int e = sc.nextInt();add(l, r, e);}for (int i = 1; i <= n; i++) {a[i] = a[i - 1] + b[i];}for (int i = 1; i <= n; i++) {System.out.print(a[i] + " ");}}static void add(int l, int r, int e) {b[l] += e;b[r + 1] -= e;}
}//二维差分
public class 拆分矩阵 {static int N = 1010;static int a[][] = new int[N][N];static int b[][] = new int[N][N];static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));public static void main(String[] args) throws IOException, InterruptedException {String s = in.readLine();String s1[] = s.split(" ");int n = Integer.valueOf(s1[0]);int m = Integer.valueOf(s1[1]);int q = Integer.valueOf(s1[2]);for (int i = 1; i <= n; i++) {String s2 = in.readLine();String s22[] = s2.split(" ");for (int j = 1; j <= m; j++) {a[i][j] = Integer.valueOf(s22[j - 1]);}}for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {insert(i, j, i, j, a[i][j]);}}while (q-- > 0) {String s3 = in.readLine();String s33[] = s3.split(" ");int x1 = Integer.valueOf(s33[0]);int y1 = Integer.valueOf(s33[1]);int x2 = Integer.valueOf(s33[2]);int y2 = Integer.valueOf(s33[3]);int e = Integer.valueOf(s33[4]);insert(x1, y1, x2, y2, e);}for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {a[i][j] = a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1] + b[i][j];}}for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {out.write(a[i][j] + " ");}out.write("\n");}out.flush();}static void insert(int x1, int y1, int x2, int y2, int e) {b[x1][y1] += e;b[x1][y2 + 1] -= e;b[x2 + 1][y1] -= e;b[x2 + 1][y2 + 1] += e;}}//三维差分  题目三体攻击(蓝桥杯真题)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;public class 三体攻击三维差分 {static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));static int N = 1500000;static int A, B, C, m;static long s[] = new long[N];static long b[] = new long[N];static long bp[] = new long[N];static int d[][] = new int[][] { { 0, 0, 0, 1 }, { 0, 0, 1, -1 }, { 0, 1, 0, -1 }, { 0, 1, 1, 1 }, { 1, 0, 0, -1 },{ 1, 0, 1, 1 }, { 1, 1, 0, 1 }, { 1, 1, 1, -1 } };static int op[][] = new int[N / 2][7];// 映射数组static int get(int i, int j, int k) {return (i * B + j) * C + k;}// 判断当前状态有无毁坏的战舰,有则true,无则反之static boolean check(int mid) {b = Arrays.copyOf(bp, bp.length);for (int i = 1; i <= mid; i++) {int x1 = op[i][0], x2 = op[i][1], y1 = op[i][2], y2 = op[i][3], z1 = op[i][4], z2 = op[i][5], h = op[i][6];b[get(x1, y1, z1)] -= h;b[get(x1, y1, z2 + 1)] += h;b[get(x1, y2 + 1, z1)] += h;b[get(x1, y2 + 1, z2 + 1)] -= h;b[get(x2 + 1, y1, z1)] += h;b[get(x2 + 1, y1, z2 + 1)] -= h;b[get(x2 + 1, y2 + 1, z1)] -= h;b[get(x2 + 1, y2 + 1, z2 + 1)] += h;}Arrays.fill(s, 0);for (int i = 1; i <= A; i++)for (int j = 1; j <= B; j++)for (int k = 1; k <= C; k++) {s[get(i, j, k)] = b[get(i, j, k)];for (int u = 1; u < 8; u++) {int x = i - d[u][0], y = j - d[u][1], z = k - d[u][2], t = d[u][3];s[get(i, j, k)] -= s[get(x, y, z)] * t;}if (s[get(i, j, k)] < 0)return true;}return false;}public static void main(String[] args) throws IOException {String s1 = in.readLine();String s11[] = s1.split(" ");A = Integer.valueOf(s11[0]);B = Integer.valueOf(s11[1]);C = Integer.valueOf(s11[2]);m = Integer.valueOf(s11[3]);String s2 = in.readLine();String s22[] = s2.split(" ");int pos = 0;// 初始化原数组(前缀和数组)for (int i = 1; i <= A; i++) {for (int j = 1; j <= B; j++) {for (int k = 1; k <= C; k++) {s[get(i, j, k)] = Integer.valueOf(s22[pos++]);}}}// 初始化差分数组for (int i = 1; i <= A; i++) {for (int j = 1; j <= B; j++) {for (int k = 1; k <= C; k++) {for (int u = 0; u < 8; u++) {int x = i - d[u][0];int y = j - d[u][1];int z = k - d[u][2];int t = d[u][3];bp[get(i, j, k)] += s[get(x, y, z)] * t;}}}}// 进行操作for (int i = 1; i <= m; i++) {String s3 = in.readLine();String s33[] = s3.split(" ");for (int j = 0; j < 7; j++) {op[i][j] = Integer.valueOf(s33[j]);}}// 进行二分int l = 1, r = m;while (l < r) {int mid = (l + r) >> 1;if (check(mid)) {r = mid;} else {l = mid + 1;}}System.out.println(r);}
}

映射数组方法

二维数组A×B,映射为一维:下标如果是i,j,则 i×B+j

三维数组A×B×C,映射为一维:下标如果是i,j,k,则(i×B+j)×C+K

Flood Fill

针对网格图

图论问题

一、找 树的直径(一点到另一点的最长路径)

  1. 任取一点x,找到离它最远的点y
  2. 找到离y点最远的点z,点z到y的距离就是这个树的直径

贪心

特点:跳跃性很强,结论证明很难
解决方法:找相似,猜

DFS|BFS

dfs

bfs

// 将bfs看成一个队列,每次取队头元素,找与其相关的元素,添至队尾
// bfs适用与求带“最短”一类的问题
int distan[];// 判重数组兼移动距离数组private static int bfs(position start, position end) {// TODO Auto-generated method stubQueue<position> queue = new LinkedList<>(); // 定义队列for (int i = 0; i < r; i++) {Arrays.fill(dis[i], -1); // 判重数组初始化}dis[start.x][start.y] = 0; // 表示起点位置,初始化距离为0queue.offer(start); // 将起点放入队列int dx[] = { -1, 0, 1, 0 }, dy[] = { 0, 1, 0, -1 }; // 表示偏移量,方向while (!queue.isEmpty()) { // 如果当前队列里面不为空,则进行队列操作position t = queue.poll(); // 取出队头元素并移除for (int i = 0; i < 4; i++) { // 进行移动操作,上下左右int x = t.x + dx[i];int y = t.y + dy[i];if (x < 0 || x >= r || y < 0 || y >= c)continue; // 地图越界if (gap[x][y] == '#')continue; // 遇到障碍if (dis[x][y] != -1)continue; // 重复经过dis[x][y] = dis[t.x][t.y] + 1; // 如果能过到这个位置上来,则这个点走的路程是上个位置走的路程+1if (end.x == x && end.y == y)return dis[x][y]; // 到终点了queue.offer(new position(x, y)); // 将新状态放入队尾}}return -1;}}//定义位置对象
class position {int x, y;public position(int x, int y) {// TODO Auto-generated constructor stubthis.x = x;this.y = y;}
}

数据结构

并查集

操作1:将两个元素合并
操作2:询问两个元素是否在一个集合当中

时间复杂度:近乎O(1)

基本原理:每个集合用一颗树来表示,树根的编号就是整个集合的编号,每个节点存储它的父节点,p[x]表示x的父节点

1.判断树根:if(p[x]==x)

2.求x的集合编号:while(p[x]!=x) x=p[x];

3.合并两个集合:px是x的集合编号,py是y的集合编号–>p[x]=y

模板题:

并查集模板题

//并查集模板
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;public class 并查集 {static int N = 10010;static int p[] = new int[N];static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));static int find(int x) {  //返回x的祖宗节点,路径压缩,关键if (p[x] != x) {p[x] = find(p[x]);}return p[x];}public static void main(String[] args) throws IOException {String s1[] = in.readLine().split(" ");int n = Integer.valueOf(s1[0]);int m = Integer.valueOf(s1[1]);for (int i = 1; i <= n; i++) {  //树的节点初始化,必要步骤p[i] = i;}while (m-- > 0) {String s2[] = in.readLine().split(" ");int op = Integer.valueOf(s2[0]);int a = Integer.valueOf(s2[1]);int b = Integer.valueOf(s2[2]);if (op == 1) {p[find(a)] = find(b);  //合并操作,将a的树根接到b的树根上去} else {if (find(a) == find(b)) {out.write("Y");out.write("\n");} else {out.write("N");out.write("\n");}}}out.flush();}}

实现单链表

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;public class Main {static int N = (int) 1e5 + 10;static int e[] = new int[N];  //节点的值static int ne[] = new int[N];  //节点的nextstatic int head;  // 头结点static int index; //当前加入的值的下标static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));// 链表初始化static void init() {head = -1;index = 0;}// 在头结点插入static void addHead(int value) {e[index] = value;ne[index] = head;head = index;index++;}// 在某个结点后面插入static void insert(int a, int value) {e[index] = value;ne[index] = ne[a];ne[a] = index;index++;}// 删除某个结点后面的数static void delete(int k) {ne[k] = ne[ne[k]];}public static void main(String[] args) throws IOException {int M = Integer.valueOf(in.readLine());init();while (M-- > 0) {String s[] = in.readLine().split(" ");if (s[0].equals("H")) {int value = Integer.valueOf(s[1]);addHead(value);} else if (s[0].equals("I")) {int a = Integer.valueOf(s[1]);int value = Integer.valueOf(s[2]);insert(a - 1, value);} else if (s[0].equals("D")) {int k = Integer.valueOf(s[1]);if (k == 0) {head = ne[head];} else {delete(k - 1);}}}for (int i = head; i != -1; i = ne[i]) {System.out.print(e[i] + " ");}}}

树的存储

数是一种特殊的图,连通,无环,所以弄懂图的相关操作之后就可以// 用邻接表存储

图的存储

// 用邻接表存储//有向图
int N;// 有几个点
int h[N] // 头结点
int e[N] //当前节点的权值
int ne[N] //节点的next指针
int index=0;void add(int a,int b){e[index]=b;ne[index]=h[a];h[a]=index;index++;
}Arrays.fill(h,-1) //初始化每一个单链表的头结点为-1//无向图无向图跟有向图步骤一样,只是在add的步骤上,再多加一步,add(a,b),add(b,a);

图的遍历

// 深度优先遍历(深度优先搜索)
boolean st[];// 遍历时不能重复,所以要有一个判重数组int dfs(int u){st[u]=true;  //st[u] 表示点u已经被遍历过了for(int i=h[u];i!=-1;i=ne[i]){int j=e[i];if(!st[j]){dfs(j);}}}// 宽度优先遍历Queue <integer> queue=new ArraysList<>();st[1]=true;  //表示1号点已经被遍历过
queue.offer(1);while(!queue.isEempty()){int t=queue.poll();for(int i=h[t];i!=-1;i=ne[i]){int j=e[i];if(!st[j]){st[j]=true;queue.offe}}
}

图的最短路径

算法总结与归纳ForLiXinBo相关推荐

  1. CAUC数据结构与算法期末复习归纳(二)

    CAUC数据结构与算法期末复习归纳(二) 二叉树 二叉树的周游 二叉树的抽象数据类型 深度优先周游二叉树或其子树 广度优先周游二叉树 二叉树的存储结构 二叉树的链式存储结构 二叉搜索树 二叉搜索树的性 ...

  2. 数据结构与算法之排序(归纳总结三)

    选择排序的基本思想是:每一趟从n-i+1 (i=1,2,-,n)个元素中选取一个关键字最小的元素作为有序序列中第i个元素.本节在介绍简单选择排序的基础上,给出了对其进行改进的算法堆排序. 1.简单选择 ...

  3. 家装软件相关算法和技术归纳

    1. 户型识别重建 准确识别 从户型图中准确识别房间.墙体.门窗等元素可能受到图像质量.细节丢失和多种表达方式的影响. 预处理:在开始识别前,先对户型图进行预处理,以消除噪声.改善图像质量和调整图像尺 ...

  4. 数据结构与算法——数据结构知识归纳

    C++中,内存分为5个区:堆.栈.自由存储区.全局/静态存储区和常量存储区. 栈:是由编译器在需要时自动分配,不需要时自动清除的变量存储区.通常存放局部变量.函数参数等. 堆:是由new分配的内存块, ...

  5. 考研数据结构中的经典算法(总归纳)

    一.线性表 1.逆转顺序表中的所有元素 算法思想:第一个元素和最后一个元素对调,第二个元素和倒数第二个元素对调,--,依此类推. void Reverse(int A[], int n) { int ...

  6. 对于一些常用的R语言的算法包的归纳(修改)

    基于R,仅供自食. 相信自己,每天多学一点. (part2来源:https://blog.csdn.net/LW_GHY/article/details/56501063) part1: 连续因变量的 ...

  7. 数据结构算法的一些归纳

    2019独角兽企业重金招聘Python工程师标准>>> 直接插入排序 说明:逐个将后一个数加到前面的排好的序中.在直接插入排序过程中,对其中一个记录的插入排序称为一次 排序:直接插入 ...

  8. 终极算法——第三章:符号学派:休谟的归纳问题

    本文为阅读总结个人认为书里概念性的.对本人有帮助的内容,仅供参考. 你是理性主义者还是经验主义者? 理性主义者认为,感官会欺骗人,而逻辑推理是通往知识的唯一可靠的道路.经验主义者认为所有推理都不可靠, ...

  9. 一文读懂图像局部特征点检测算法

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自|新机器视觉 研究图像特征检测已经有一段时间了,图像特征检 ...

最新文章

  1. 调查问卷_员工满意度调查问卷
  2. 发现问题,是解决问题的第一步
  3. 获取并编译linux源码,android获取源代码、编译、命令
  4. 小小聊天室,慢慢的回忆啊!(TCP 通信实现)
  5. Java回忆录之英勇黄铜V
  6. 我的iOS学习历程 - UISegmentedControl
  7. dom选择方法的区别
  8. 微擎模块安装文件manifest.xml
  9. python和java选择哪个-Python和Java该如何选择?选哪个好?
  10. (转)李开复哥伦比亚大学演讲:如何才能不错过人工智能时代
  11. ecshop设置会员头像
  12. 手机共享电脑Wifi软件网络抓包
  13. cAdvisor的使用
  14. 桌面版linux装哪个版本好用,linux桌面版哪个版本好用?
  15. 如何确定直流电机驱动的 PWM 频率
  16. brew | brew cask | yum | apt-get
  17. CAD中用lisp程序实现批量偏移_求一个cad lisp 双向偏移的代码
  18. 流式布局之javascript实现照片瀑布流以及Macy.js插件实现瀑布流
  19. 仙剑五手游服务器维护,新仙剑奇侠传游戏进不去怎么办 游戏进不去解决方法...
  20. ospf路由概念简述(入门)

热门文章

  1. H5企业网站模板-蓝绿过渡色功能菜单齐全
  2. 查找你的域名DNS服务器
  3. 小猪的C语言快速入门系列(一)
  4. 水下自动循迹机器人_全自动循迹灭火机器人的设计
  5. 2005年4月24日
  6. Blog of Friends
  7. 国产单片机(GD32E103)与MSP485通讯问题
  8. Latex参考文献软件推荐
  9. 在对话框显示图片的多种方法(上)
  10. 桌面备忘录便签设置提醒教程