写这篇博客的今天是19年的省赛考前的最后一天了,想写一些小白萌新们受益的东西
从最常考的全排列开始吧~
全排列模板1,最常用的写法
public class 全排列_模板1 {
public static void main(String[] args) {
dfs(0);
System.out.println(ans);//9的全排有362880种
}
static int[] a = new int[] {1,2,3,4,5,6,7,8,9};
static int n=9,ans=0;
static void dfs(int m) {
if(m>=n) {
System.out.println("一些核心的操作 比如ans:"+ans);
ans++;
for(int i=0;i
全排列模板2,使用标记数组的写法
public class 全排列_模板2 {
public static void main(String[] args) {
vis = new boolean[n];
b = new int[n];
dfs(0);
System.out.println(ans);//9的全排有362880种
}
static int[] a = new int[] {1,2,3,4,5,6,7,8,9};
static int[] b;
static boolean[] vis;
static int n=9,ans=0;
static void dfs(int m) {
if(m>=n) {
System.out.println("一些核心的操作 比如ans:"+ans);
ans++;
for(int i=0;i
下面是需要排重的全排_模板
在上面模板上使用了哈希表查重,把一些数组并接成字符串
import java.util.HashSet;
public class 全排列_模板3 {
public static void main(String[] args) {
dfs(0);
System.out.println(ans);//9的全排有362880种
System.out.println(set.size());//1680
}
static int[] a = new int[] {1,1,1,2,2,2,3,3,3};
static int n=9,ans=0;
static HashSet set = new HashSet<>();
static void dfs(int m) {
if(m>=n) {
System.out.println("一些核心的操作 比如ans:"+ans);
ans++;
String s="";
for(int i=0;i
使用哈希表查重后是无序的,那么遇到需要打印字典序的有重复元素的全排呢
leetcode 46. 全排列
leetcode 47. 全排列 II
子集的写法也和全排很相似
leetcode 78. 子集(Subsets) beat 100%
leetcode 90. 子集 II(Subsets II) beat 98.57%
判断闰年
static boolean is(int x) {
return x%400==0 || (x%4==0 && x%100!=0);
}
筛素数O()
static boolean is(int n) {
if(n==1)
return false;
for(int i=2;i*i<=Math.sqrt(n);i++)
if(n%i==0)
return false;
return true;
}
倍筛法_素数O(nlogn)
public class 倍筛模板 {
public static void main(String[] args) {
boolean[] is = new boolean[1000005];
is[1] = true;//true表示不是素数
for(int i=2;i<1000005;i++)
if(!is[2])
for(int j=2*i;j<1000005;j+=i)
is[j] = true;
System.out.println(is[2004]);
}
}
01背包
public class _01背包 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int m = in.nextInt();//大小
int n = in.nextInt();//物品数
int[] dp = new int[m+5];//开背包质量的大小
for(int i=1;i<=n;i++) {
int v = in.nextInt();//物品体积
int w = in.nextInt();//物品价值
for(int j=m;j>=v;j--)
dp[j] = Math.max(dp[j], dp[j-v]+w);
}
System.out.println(dp[m]);
}
}
完全背包
import java.util.Scanner;
public class _完全背包 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int m = in.nextInt();//大小
int n = in.nextInt();//物品数
int[] dp = new int[m+5];//开背包质量的大小
for(int i=1;i<=n;i++) {
int v = in.nextInt();//物品体积
int w = in.nextInt();//物品价值
for(int j=v;j<=m;j++)
dp[j] = Math.max(dp[j], dp[j-v]+w);
}
System.out.println(dp[m]);
}
}
最小公倍数gcd
static int gcd(int a,int b) {
return b==0?a:gcd(b,a%b);
}
最大公约数lcm
static int lcm(int a,int b) {
return a*b/gcd(a,b);
}
多个数共同的gcd和lcm模板
static int gcd(int[] a) {
int n = a.length;
int g = a[0];
for(int i=1;i
二分答案_模板
蓝桥杯 2017年第八届真题 分巧克力 经典的二分答案 输入挂
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;//按照题意写
}
二分lower_bound的实现(找到第一个大于等于给定值key的那个数)如[1,2,2,3]查找2,会返回第一个2的下标
public static int lowerBound(int []nums,int l,int r,int target){
while(l<=r){//r=n-1
int m = (l+r)/2;
if(nums[m]>=target) r= m-1;
else l = m +1;
}
return l;
}
upper_bound的实现(要求在按照非递减顺序排好序的数组中找到第一个大于给定值key的那个数)(不常用)
public static int upperBound(int []nums ,int l,int r, int target){
while(l
各种排序实现
大数类BigInteger和BigDecimal及方法API
考场上查API
进制问题,如有价值1,2,4,8等价值的硬币,如何用最小的硬币数凑出100元
static int f(int n,int k) {//调用API转成k进制,缺点题目有上界为8
int ans=0;
String s = Integer.toString(n, k);
System.out.println(s);
for(int i=0;i
头条面试题:找钱问题,共1024,64,16,4,1几种面值
static void solve(){
Scanner cin = new Scanner(System.in);
int N = 1024-cin.nextInt(), ans = 0;
for(int i=0; i<4; i++){
ans += N/arr[i];
N %= arr[i];
}
System.out.println(ans);
}
!
堆的应用,给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串,判断字符串是否有效
leetcode 20. 有效的括号(Valid Parentheses)
public boolean isValid(String s) {
if(s==null||s.equals(""))
return true;
char[] ch = s.toCharArray();
Stack stack = new Stack<>();
for(int i=0;i
快速幂及矩阵快速幂模板
矩阵幂_快速幂_矩阵乘法_模板
static long mpow(long a,long n) {//快速幂,mod一般题目给1e9+7
if(n==0 || a==1)
return 1;
long ans=1;
while(n!=0) {
if(n%2==1)
ans = a*ans%mod;
a=a*a%mod;
n>>=1;
}
return ans;
}
矩阵乘法模板
//这里是矩阵的乘法模板,默认方阵
static int[][] mul(int[][] a,int[][] b){
int n = a.length;
int[][] ans = new int[n][n];
for(int i=0;i
矩阵快速幂模板
//矩阵快速幂_模板
static int[][] mpow(int[][] a,int n){
int N = a.length;
int[][] ans = new int[N][N];
for(int i=0;i0) {//写 n!=0也行,会快些么,反正位运算是会快的.这个不清楚
if((n&1)==1)
ans = mul(ans,a);
a = mul(a,a);
n>>=1;
}
return ans;
}
阶乘逆元求组合数C(n,m)模板_O(nlogn)
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
f = new long[n+5];
inv = new long[n+5];
f[0]=1;
for(int i=1;i>=1;
}
return ans;
}
欧拉函数模板 定义:小于n的正整数中与n互质的数的数目(φ(1)=1)
static int Euler(int n) {//O(n) 有时候需要long
int ans=n;
for(int i=2;i<=n;i++)
if(n%i==0) {
ans=ans/i*(i-1);
while(n%i==0)
n/=i;
}
return ans;
}
static int Euler(int n) {//O(sqrt(n))
int ans=n;
for(int i=2;i*i<=n;i++)
if(n%i==0) {
ans=ans/i*(i-1);////n*(1-(1/p))转化为n/p*(p-1)
while(n%i==0)
n/=i;
}
if(n>1)//优化 O(sqrt(n)) 不过要在出口 if(n>1)ans/n*(n-1) O(n)不用
ans=ans/n*(n-1);
return ans;
}
前缀和模板
import java.util.Scanner;
public class 前缀和模板 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] sum = new int[n+1];
for(int i=1;i<=n;i++)
sum[i] = sum[i-1] + in.nextInt();//前i个数的和
}
}
线段树模板
并查集模板
static int n,m,cnt=0;
static int[] f = new int[10005];//初始化一般是f[i]=i
static int find(int x) {
if(f[x]==x)
return x;
return f[x] = find(f[x]);
}
static void union(int x,int y) {
int a = find(x);
int b = find(y);
if(a!=b) {
f[a] = b;
cnt++;
}
}
dfs求联通块模板
static int n,m;
static int[][] vis;
static char[][] ch;
static int[] dx = new int[] {1,1,1,0,0,-1,-1,-1};
static int[] dy = new int[] {0,-1,1,1,-1,1,0,-1};
static void dfs(int t,int x,int y) {// hdu1241 油田问题 八联通
vis[x][y] = t;
for(int i=0;i<8;i++)
if(x+dx[i]>=0 && x+dx[i]=0 && y+dy[i]
int t=0;
for(int i=0;i
最小生成树模板
static int n,m,cnt=0,ans=0;
static int[] f;
static int find(int x) {
if(f[x]==x)
return x;
return f[x] = find(f[x]);
}
static int union(int x,int y) {
int a = find(x);
int b = find(y);
if(a!=b) {
f[a] = b;
return 1;
}
return 0;
}
static class Edge implements Comparable{
int a,b,c;
public Edge(int a,int b,int c) {
this.a = a;
this.b = b;
this.c = c;
}
@Override
public int compareTo(Edge o) {
return this.c - o.c;
}
}
public static void main(String[] args) {
InputReader in = new InputReader(System.in); //用它来代替Scanner。
while(true) {
n = in.nextInt();
if(n==0)
break;
m = n*(n-1)/2;
cnt=0;
ans=0;
f = new int[n+5];
for(int i=1;i<=n;i++)
f[i] = i;
PriorityQueue pq = new PriorityQueue<>();
for(int i=1;i<=m;i++) {
int a = in.nextInt();
int b = in.nextInt();
int c = in.nextInt();
int d = in.nextInt();
if(d==1)
cnt+=union(a,b);
else
pq.add(new Edge(a, b, c));
}
while(!pq.isEmpty()) {
Edge u = pq.poll();
if(union(u.a, u.b)==1) {
cnt++;
ans+=u.c;
if(cnt==n-1)
break;
}
}
System.out.println(ans);
}
}
输入挂模板
//解决javaIO读取过慢的方法,利用该类读取输入数据,不要用Scanner!!!
static class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
}
拓扑排序模板
蓝桥杯 卡勒沃夫之弱水路三千(提高型) 拓扑排序+Map
static ArrayList list = new ArrayList<>();
static ArrayList[] edge = new ArrayList[105];
while(m-->0) {//建图 邻接表 并且用w[i]记录入度
String s1 = in.next();
String s2 = in.next();
if(!map.containsKey(s1))
map.put(s1,n++);
if(!map.containsKey(s2))
map.put(s2,n++);
w[map.get(s2)]++;
edge[map.get(s1)].add(map.get(s2));
}
for(int i:map.values())//把边为0的放进队列
if(w[i]==0)
q.add(i);
while(!q.isEmpty()) {
int u = q.poll();
list.add(u);
for(int v:edge[u]) {
w[v]--;
if(w[v]==0)
q.add(v);
}
}
dijkstra模板O(n^2)
dijkstra邻接表+优先队列模板O(nlogn)