acwing 基礎演算法班 java實現
阿新 • • 發佈:2022-04-18
第一講 基礎演算法
快速排序
AcWing 785. 快速排序
package com.acwing; import java.util.*; public class ac785 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] nums = new int[n]; for (int i = 0; i < n; i++) nums[i] = sc.nextInt(); sortQuick(nums, 0, n - 1); for (int x : nums) System.out.print(x + " "); } public static void sortQuick(int[] nums, int l, int r) { if (l >= r) return; int x = nums[l], i = l - 1, j = r + 1; while (i < j) { while (nums[++i] < x) ; while (nums[--j] > x) ; if (i < j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } } sortQuick(nums, l, j); sortQuick(nums, j + 1, r); } }
AcWing 786. 第k個數
import java.util.*; public class ac786 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int k = sc.nextInt(); int[] nums = new int[n]; for (int i = 0; i < n; i++) nums[i] = sc.nextInt(); int out = sortQuick(nums, 0, n - 1, k); System.out.println(out); } public static int sortQuick(int[] nums, int l, int r, int k) { if (l == r) return nums[l]; int x = nums[l], i = l - 1, j = r + 1; while (i < j) { while (nums[++i] < x) ; while (nums[--j] > x) ; if (i < j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } } int sl = j - l + 1; if (k <= sl) return sortQuick(nums, l, j, k); else return sortQuick(nums, j + 1, r, k - sl); } }
歸併排序
AcWing 787. 歸併排序
import java.util.Scanner; public class ac787 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] nums = new int[n]; for (int i = 0; i < n; i++) nums[i] = sc.nextInt(); merge_sort(nums, 0, n - 1); for (int x : nums) System.out.print(x + " "); } public static void merge_sort(int[] nums, int l, int r) { if (l >= r) return; int mid = (l + r) >> 1; merge_sort(nums, l, mid); merge_sort(nums, mid + 1, r); int index = 0, i = l, j = mid + 1; int[] temp = new int[r - l + 1]; while (i <= mid && j <= r) { if (nums[i] <= nums[j]) temp[index++] = nums[i++]; else temp[index++] = nums[j++]; } while (i <= mid) temp[index++] = nums[i++]; while (j <= r) temp[index++] = nums[j++]; for (i = l, j = 0; i <= r; i++, j++) nums[i] = temp[j]; } }
AcWing 788. 逆序對的數量
package com.acwing;
import java.util.Scanner;
public class ac788 {
static int count = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] nums = new int[n];
for (int i = 0; i < n; i++) nums[i] = sc.nextInt();
System.out.println(merge_sort(nums, 0, n - 1));
}
public static long merge_sort(int[] nums, int l, int r) {
if (l >= r) return 0;
int mid = (l + r) >> 1;
long res = merge_sort(nums, l, mid) + merge_sort(nums, mid + 1, r);
int index = 0, i = l, j = mid + 1;
int[] temp = new int[r - l + 1];
while (i <= mid && j <= r) {
if (nums[i] <= nums[j]) temp[index++] = nums[i++];
else {
temp[index++] = nums[j++];
res+=mid-i+1;
}
}
while (i <= mid) temp[index++] = nums[i++];
while (j <= r) temp[index++] = nums[j++];
for (i = l, j = 0; i <= r; i++, j++) nums[i] = temp[j];
return res;
}
}
二分
模板1: 區間 [l,r] 劃分為 [l,mid] 和 [mid+1,r] 時使用
int besearch_1(int l,int r){
while(l<r){
int mid=l+r>>1;
if(check(mid)) r=mid;
else l=mid+1
}
return l;
}
模板2: 區間 [l,r] 劃分為 [l,mid-1] 和 [mid,r] 時使用
int besearch_2(int l,int r){
while(l<r){
int mid=l+r+1>>1;
if(chech(mid)) l=mid;
else r=mid-1;
}
return l;
}
AcWing 789. 數的範圍
import java.util.Scanner;
public class ac789 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[] nums = new int[n];
for (int i = 0; i < n; i++) nums[i] = sc.nextInt();
while (m-- > 0) {
int target = sc.nextInt();
int left = get_left(nums, target);
if (nums[left] != target) {
System.out.println("-1 -1");
continue;
}
int right = get_right(nums, target);
System.out.println(left + " " + right);
}
}
public static int get_left(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left < right) {
int mid = left + right >> 1;
if (nums[mid] >= target) {
right = mid;
} else left = mid + 1;
}
return right;
}
public static int get_right(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left < right) {
int mid = left + right + 1 >> 1;
if (nums[mid] <= target) {
left = mid;
} else right = mid - 1;
}
return left;
}
}
AcWing 790. 數的三次方根
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
double x=sc.nextDouble();
double l=-10000,r=10000;
while (r-l>1e-8){
double mid=(l+r)/2;
if(mid*mid*mid>=x) r=mid;
else l=mid;
}
System.out.println(String.format("%.6f", l));
}
}
字首和與差分
AcWing 795. 字首和
import java.util.Scanner;
public class lc795 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[] nums = new int[n+1];
int[] table = new int[n + 1];
for (int i = 1; i <= n; i++) {
nums[i] = sc.nextInt();
table[i] = table[i-1] + nums[i];
}
while (m-- > 0) {
int l = sc.nextInt();
int r = sc.nextInt();
System.out.println(table[r] - table[l-1]);
}
}
}
AcWing 796. 子矩陣的和
import java.util.Scanner;
public class ac796 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n= sc.nextInt();
int m=sc.nextInt();
int q=sc.nextInt();
int[][] table=new int[n+1][m+1];
int[][] dp=new int[n+1][m+1];
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
table[i][j]=sc.nextInt();
dp[i][j]=dp[i-1][j]+dp[i][j-1]+table[i][j]-dp[i-1][j-1];
}
}
while (q-->0){
int x1=sc.nextInt();
int y1=sc.nextInt();
int x2=sc.nextInt();
int y2=sc.nextInt();
System.out.println(dp[x2][y2]-dp[x1-1][y2]-dp[x2][y1-1]+dp[x1-1][y1-1]);
}
}
}
AcWing 797. 差分
import java.util.Scanner;
public class ac797 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m=sc.nextInt();
int[] nums = new int[n + 1];
int[] table = new int[n + 2];
for (int i = 1; i <= n; i++) {
nums[i] = sc.nextInt();
table[i] += nums[i];
table[i + 1] -= nums[i];
}
// for (int x : nums) System.out.print(x + "\t");
// System.out.println();
// for (int x : table) System.out.print(x + "\t");
// System.out.println();
while (m-->0){
int l=sc.nextInt();
int r=sc.nextInt();
int c=sc.nextInt();
table[l]+=c;
table[r+1]-=c;
}
for(int i=1;i<=n;i++){
table[i]+=table[i-1];
System.out.print(table[i]+" ");
}
}
}
AcWing 798. 差分矩陣
package com.acwing;
import java.util.Scanner;
public class ac798 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int q = sc.nextInt();
int[][] nums = new int[n + 1][m + 1];
int[][] dp = new int[n + 2][m + 2];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
nums[i][j] = sc.nextInt();
insert(dp,i,j,i,j,nums[i][j]);
}
}
while (q-->0){
int x1=sc.nextInt();
int y1=sc.nextInt();
int x2=sc.nextInt();
int y2=sc.nextInt();
int c=sc.nextInt();
insert(dp,x1,y1,x2,y2,c);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
dp[i][j]+=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1];
System.out.print(dp[i][j]+" ");
}
System.out.println();
}
}
public static void insert(int[][] dp, int x1, int y1, int x2, int y2, int c) {
dp[x1][y1] += c;
dp[x2 + 1][y1] -= c;
dp[x1][y2 + 1] -= c;
dp[x2+1][y2+1] += c;
}
}
雙指標
AcWing 799. 最長連續不重複子序列
import java.util.*;
public class ac799 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int[] nums=new int[n];
for(int i=0;i<n;i++) nums[i]=sc.nextInt();
int left=0;
HashMap<Integer,Integer> map=new HashMap();
int max=Integer.MIN_VALUE;
for(int i=0;i<n;i++){
if(map.containsKey(nums[i])){
left=Math.max(left,map.get(nums[i])+1);
}
map.put(nums[i],i);
max=Math.max(max,i-left+1);
}
System.out.println(max);
}
}
AcWing 800. 陣列元素的目標和
package com.acwing;
import java.util.Scanner;
public class ac800 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int x = sc.nextInt();
int[] a = new int[n];
int[] b = new int[m];
for (int i = 0; i < n; i++) a[i] = sc.nextInt();
for (int i = 0; i < m; i++) b[i] = sc.nextInt();
int i = 0, j = m-1;
while (i < n && j >=0) {
if(a[i]+b[j]==x) break;
else if(a[i]+b[j]>x) j--;
else i++;
}
System.out.println(i+" "+j);
}
}
AcWing 2816. 判斷子序列
import java.util.Scanner;
public class ac2816 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[] a = new int[n];
int[] b = new int[m];
for (int i = 0; i < n; i++) a[i] = sc.nextInt();
for (int j = 0; j < m; j++) b[j] = sc.nextInt();
int i=0,j=0;
while (i<n&&j<m){
if(a[i]==b[j])i++;
j++;
}
if(i==n) System.out.println("Yes");
else System.out.println("No");
}
}
位運算
AcWing 801. 二進位制中1的個數
import java.util.Scanner;
public class ac801 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
while (n-->0){
int x=sc.nextInt();
int count=0;
while (x!=0){
if((x&1)==1) count++;
x=x>>1;
}
System.out.print(count+" ");
}
}
}
離散化
AcWing 802. 區間和
package com.acwing;
import java.util.*;
public class ac802 {
static TreeSet<Integer> set=new TreeSet<>();
static List<Integer> alls=new ArrayList<>();
static List<int[]> adds=new ArrayList<>();
static List<int[]> query=new ArrayList<>();
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int m=sc.nextInt();
for(int i=0;i<n;i++){
int x=sc.nextInt();
int c=sc.nextInt();
adds.add(new int[]{x,c});
set.add(x);
}
for(int i=0;i<m;i++){
int l=sc.nextInt();
int r=sc.nextInt();
query.add(new int[]{l,r});
set.add(l);
set.add(r);
}
for(int x:set) alls.add(x);
Collections.sort(alls);
for(int x:alls) System.out.print(x+" ");
int[] a=new int[alls.size()+1];
int[] s=new int[alls.size()+1];
for(int[] add:adds){
int x=find(add[0]);
a[x]+=add[1];
}
for(int i=1;i<a.length;i++){
s[i]=s[i-1]+a[i];
}
for(int[] que:query){
int l=find(que[0]);
int r=find(que[1]);
System.out.println(s[r]-s[l-1]);
}
}
public static int find(int x){
int l=0,r=alls.size()-1;
while (l<r){
int mid=l+r>>1;
if(alls.get(mid)>=x) r=mid;
else l=mid+1;
}
return r+1;
}
}
區間合併
AcWing 803. 區間合併
package com.acwing;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class ac803 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int[][] a=new int[n][2];
for(int i=0;i<n;i++){
a[i][0]=sc.nextInt();
a[i][1]=sc.nextInt();
}
Arrays.sort(a,(Comparator.comparingInt(o -> o[0])));
int ed=Integer.MIN_VALUE;
int count=0;
for(int[] x:a){
System.out.println(x[0]+" "+x[1]);
if(ed<x[0]){
ed=x[1];
count++;
}else {
ed=Math.max(ed,x[1]);
}
}
System.out.println(count);
}
}
第二講 資料結構
單鏈表
AcWing 826. 陣列模擬單鏈表
import java.util.List;
import java.util.Scanner;
public class ac826 {
static int N=100010;
static int head,idx;
static int[] e=new int[N];
static int[] ne=new int[N];
public static void init(){
head=-1;
idx=0;
}
public static void add_head(int x){
e[idx]=x;
ne[idx]=head;
head=idx;
idx++;
}
public static void add(int k,int x){
e[idx]=x;
ne[idx]=ne[k];
ne[k]=idx;
idx++;
}
public static void remove(int k) {
ne[k]=ne[ne[k]];
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
init();
while (n-->0){
char c=sc.next().charAt(0);
if(c=='H'){
int x=sc.nextInt();
add_head(x);
}
else if(c=='D'){
int k=sc.nextInt();
if(k==0) head=ne[head];
else remove(k-1);
}
else if(c=='I'){
int k=sc.nextInt();
int x=sc.nextInt();
add(k-1,x);
}
}
for(int i=head;i!=-1;i=ne[i]){
System.out.print(e[i]+" ");
}
}
}
AcWing 827. 陣列模擬雙鏈表
棧和佇列
AcWing 828. 陣列模擬棧
package com.acwing;
import java.util.Scanner;
public class ac828 {
// push x – 向棧頂插入一個數 x;
// pop – 從棧頂彈出一個數;
// empty – 判斷棧是否為空;
// query – 查詢棧頂元素
static int N=100010;
static int[] stk=new int[N];
static int tt=0;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
while (n-->0){
String op=sc.next();
if(op.equals("push")){
int x=sc.nextInt();
stk[tt++]=x;
}else if(op.equals("pop")){
tt--;
}else if(op.equals("query")){
System.out.println(stk[tt-1]);
}else if(op.equals("empty")){
if(tt>0) System.out.println("NO");
else System.out.println("YES");
}
}
}
}
AcWing 3302. 表示式求值
import java.util.*;
public class ac3302 {
static Stack<Character> op = new Stack<>();
static Stack<Integer> num = new Stack<>();
static HashMap<Character, Integer> map = new HashMap<>();
public static void main(String[] args) {
map.put('+', 1);
map.put('-', 1);
map.put('*', 2);
map.put('/', 2);
char[] str = new Scanner(System.in).next().toCharArray();
for (int i = 0; i < str.length; i++) {
char c = str[i];
if (Character.isDigit(c)) {
int x = 0, j = i;
while (j < str.length && Character.isDigit(str[j])) {
x = x * 10 + str[j++] - '0';
}
i=j-1;
num.push(x);
}
else if (c == '(') op.push(c);
else if (c == ')') {
while (op.peek() != '(') eval();
op.pop();
}
else {
while (!op.isEmpty()&&op.peek()!='(' && map.get(op.peek()) >= map.get(c)) eval();
op.push(c);
}
}
while (op.size() > 0) eval();
System.out.println(num.peek());
}
public static void eval() {
int b = num.pop();
int a = num.pop();
char c = op.pop();
int x;
if (c == '+') x = a + b;
else if (c == '-') x = a - b;
else if (c == '*') x = a * b;
else x = a / b;
num.push(x);
}
}
AcWing 829. 模擬佇列
package com.acwing;
import java.util.Scanner;
public class ac829 {
static int N=1000010;
static int[] que=new int[N];
static int hh=0,tt=-1;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
while (n-->0){
String s=sc.next();
if(s.equals("push")){
int x=sc.nextInt();
que[++tt]=x;
}else if(s.equals("empty")){
if(hh>tt) System.out.println("YES");
else System.out.println("NO");;
}else if(s.equals("pop")){
hh++;
}else if(s.equals("query")){
System.out.println(que[hh]);
}
}
}
}
AcWing 830. 單調棧
import java.util.Scanner;
import java.util.Stack;
public class ac830 {
public static void main(String[] args) {
Stack<Integer> stk=new Stack<>();
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
for(int i=0;i<n;i++){
int x=sc.nextInt();
if(i==0){
stk.push(x);
System.out.print(-1+" ");
}else {
while (!stk.isEmpty()&&stk.peek()>=x){
stk.pop();
}
if(stk.isEmpty()) System.out.print(-1+" ");
else System.out.print(stk.peek()+" ");
stk.push(x);
}
}
}
}
AcWing 154. 滑動視窗 && 單調佇列
import java.util.*;
public class ac154 {
static int N = 10000010;
static int[] a = new int[N];
static int[] q = new int[N];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
for (int i = 0; i < n; i++) a[i] = sc.nextInt();
int hh = 0, tt = -1;
for (int i = 0; i < n; i++) {
if (hh <= tt && q[hh] < i - k + 1) hh++;
while (hh <= tt && a[q[tt]] >= a[i]) tt--;
q[++tt] = i;
if(i>=k-1) System.out.print(a[q[hh]]+" ");
}
System.out.println();
hh=0;
tt=-1;
for(int i=0;i<n;i++){
if(hh<=tt&&q[hh]<i-k+1) hh++;
while (hh<=tt&&a[q[tt]]<=a[i]) tt--;
q[++tt]=i;
if(i>=k-1) System.out.print(a[q[hh]]+" ");
}
}
}
Trie
AcWing 835. Trie字串統計
import java.util.Scanner;
public class ac835 {
static int N = 100010;
static int[][] son = new int[N][26];
static int[] cnt = new int[N];
static char[] str;
static int idx = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
while (n-- > 0) {
char c = sc.next().charAt(0);
str = sc.next().toCharArray();
if (c == 'I') insert(str);
else System.out.println(query(str));
}
}
public static void insert(char[] str) {
int p = 0;
for (int i = 0; i < str.length; i++) {
int u = str[i] - 'a';
if (son[p][u] == 0) son[p][u] = ++idx;
p = son[p][u];
}
cnt[p]++;
}
public static int query(char[] str) {
int p = 0;
for (int i = 0; i < str.length; i++) {
int u = str[i] - 'a';
if (son[p][u] == 0) return 0;
p = son[p][u];
}
return cnt[p];
}
}
AcWing 143. 最大異或對
並查集
AcWing 836. 合併集合
import java.util.Scanner;
public class ac836 {
static int N = 100010;
static int[] p = 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 = 0; i <= n; i++) p[i] = i;
while (m-- > 0) {
char c = sc.next().charAt(0);
int a = sc.nextInt();
int b = sc.nextInt();
if(c=='M'){
p[find(a)]=find(b);
}else {
if(find(a)==find(b)) System.out.println("Yes");
else System.out.println("No");
}
}
}
public static int find(int x) {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
}
AcWing 837. 連通塊中點的數量
import java.util.Scanner;
public class ac837 {
static int N=100010;
static int[] p=new int[N];
static int[] size=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=0;i<n;i++){
p[i]=i;
size[i]=1;
}
while (m-->0){
String s=sc.next();
if(s.equals("C")){
int a=sc.nextInt();
int b=sc.nextInt();
if(find(a)==find(b)) continue;
size[find(b)]+=size[find(a)];
p[find(a)]=find(b);
}else if(s.equals("Q1")){
int a=sc.nextInt();
int b=sc.nextInt();
if(find(a)==find(b)) System.out.println("Yes");
else System.out.println("No");
}else {
int a=sc.nextInt();
System.out.println(size[find(a)]);
}
}
}
public static int find(int x){
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
}
AcWing 240. 食物鏈
import java.util.Scanner;
public class ac240 {
static int N = 50010;
static int[] p = new int[N];
static int[] d = 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 = 0; i < n; i++) p[i] = i;
int ans = 0;
while (m-- > 0) {
int t = sc.nextInt();
int x = sc.nextInt();
int y = sc.nextInt();
if(x>n||y>n) ans++;
else {
int px=find(x),py=find(y);
if(t==1){
if(px==py&&(d[x]-d[y])%3!=0) ans++;
else if(px!=py){
p[px]=py;
d[px]=d[y]-d[x];
}
}else {
if(px==py&&(d[x]-d[y]-1)%3!=0) ans++;
else if(px!=py){
p[px]=py;
d[px]=d[y]+1-d[x];
}
}
}
}
System.out.println(ans);
}
public static int find(int x) {
if (p[x] != x) {
int t = find(p[x]);
d[x] += d[p[x]];
p[x]=t;
}
return p[x];
}
}
堆
AcWing 838. 堆排序
import java.util.PriorityQueue;
import java.util.Scanner;
public class ac838 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int m=sc.nextInt();
PriorityQueue<Integer> que=new PriorityQueue<>();
while (n-->0){
int x=sc.nextInt();
que.offer(x);
}
while (!que.isEmpty()&&m>0){
System.out.print(que.poll()+" ");
m--;
}
}
}
第三章 搜尋與圖論
DFS
AcWing 842. 排列數字
import java.util.*;
public class ac842 {
static List<List<Integer>> ans = new ArrayList<>();
static List<Integer> temp = new ArrayList<>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
boolean[] used = new boolean[n];
dfs(n, used);
for (List<Integer> res : ans) {
for (int x : res) System.out.print(x + " ");
System.out.println();
}
}
public static void dfs(int n, boolean[] used) {
if (temp.size() == n) {
ans.add(new ArrayList<>(temp));
return;
}
for (int i = 0; i < n; i++) {
if (!used[i]) {
used[i] = true;
temp.add(i + 1);
dfs(n, used);
temp.remove(temp.size() - 1);
used[i] = false;
}
}
}
}
AcWing 843. n-皇后問題
package com.acwing;
import java.util.Arrays;
import java.util.Scanner;
public class ac843 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
char[][] chess = new char[n][n];
for (char[] ch : chess) Arrays.fill(ch, '.');
dfs(chess, 0);
}
public static void dfs(char[][] chess, int index) {
if (index == chess.length) {
print_chess(chess);
}
for (int j = 0; j < chess.length; j++) {
if (valid(chess, index, j)) {
chess[index][j] = 'Q';
dfs(chess, index + 1);
chess[index][j] = '.';
}
}
}
public static void print_chess(char[][] chess) {
for (char[] ch : chess) {
for (char c : ch) System.out.print(c);
System.out.println();
}
System.out.println();
}
public static boolean valid(char[][] chess, int x, int y) {
for (int i = 0; i < x; i++) if (chess[i][y] == 'Q') return false;
for (int i = x, j = y; i >= 0 && j >= 0; i--, j--) if (chess[i][j] == 'Q') return false;
for (int i = x, j = y; i >=0 && j <chess.length; i--, j++) if (chess[i][j] == 'Q') return false;
return true;
}
}
BFS
AcWing 844. 走迷宮
package com.acwing;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class ac844 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[][] a = new int[n][m];
int[][] b = new int[n][m];
for (int[] bb : b) Arrays.fill(bb, -1);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
a[i][j] = sc.nextInt();
}
}
boolean[][] used = new boolean[n][m];
Queue<int[]> que = new LinkedList<>();
que.offer(new int[]{0, 0});
b[0][0] = 0;
while (!que.isEmpty()) {
int size = que.size();
for (int p = 0; p < size; p++) {
int[] pos = que.poll();
int x = pos[0];
int y = pos[1];
used[x][y] = true;
int[] dx = {1, -1, 0, 0,};
int[] dy = {0, 0, 1, -1};
for (int k = 0; k < 4; k++) {
int new_x = x + dx[k];
int new_y = y + dy[k];
if (new_x >= 0 && new_x < n && new_y >= 0 && new_y < m && a[new_x][new_y] != 1 && b[new_x][new_y] == -1) {
b[new_x][new_y] = b[x][y] + 1;
que.offer(new int[]{new_x, new_y});
}
}
}
}
System.out.println(b[n - 1][m - 1]);
}
}
樹與圖的深度優先遍歷
AcWing 846. 樹的重心
import java.util.*;
public class ac846 {
static HashMap<Integer, List<Integer>> tree = new HashMap<>();
static int ans=Integer.MAX_VALUE;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
boolean[] used=new boolean[n+1];
for (int i = 0; i < n - 1; i++) {
int a = sc.nextInt(), b = sc.nextInt();
insert(a, b);
insert(b, a);
}
// for(int k:tree.keySet()){
// System.out.print(k+" :");
// List<Integer> t=tree.get(k);
// for(int x:t) System.out.print(x+" ");
// System.out.println();
// }
dfs(1,n,used);
System.out.println(ans);
}
public static void insert(int x, int y) {
List<Integer> temp = tree.getOrDefault(x, new ArrayList<>());
temp.add(y);
tree.put(x, temp);
}
public static int dfs(int root,int n,boolean[] used){
used[root]=true;
List<Integer> temp=tree.get(root);
if(temp==null) return 1;
int count=1;
int res=0;
for(int x: temp){
if(!used[x]){
int child=dfs(x,n,used);
res=Math.max(res,child);
count+=child;
}
}
res=Math.max(res,n-count);
ans=Math.min(ans,res);
return count;
}
}
樹與圖的廣度優先遍歷
AcWing 847. 圖中點的層次
import java.util.*;
public class ac847 {
static HashMap<Integer, List<Integer>> map = new HashMap<>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
boolean[] used = new boolean[n + 1];
for (int i = 0; i < m; i++) {
int a = sc.nextInt();
int b = sc.nextInt();
insert(a, b);
insert(b, a);
}
Queue<Integer> que = new LinkedList<>();
que.offer(1);
int count = 0;
boolean flag = false;
// for (int k : map.keySet()) {
// System.out.print(k + " :");
// List<Integer> t = map.get(k);
// for (int x : t) System.out.print(x + " ");
// System.out.println();
// }
// System.out.println("----------");
while (!que.isEmpty()) {
int size = que.size();
List<Integer> next=new ArrayList<>();
for (int i = 0; i < size; i++) {
int x = que.poll();
if(x==n) flag=true;
used[x] = true;
List<Integer> temp = map.getOrDefault(x,new ArrayList<>());
for (int y : temp) next.add(y);
}
if (flag) break;
for(int x:next) if(!used[x]) que.offer(x);
//System.out.println();
count++;
}
if(flag==false) System.out.println(-1);
else System.out.println(count);
}
public static void insert(int x, int y) {
List<Integer> temp = map.getOrDefault(x, new ArrayList<>());
temp.add(y);
map.put(x, temp);
}
}
拓撲排序
AcWing 848. 有向圖的拓撲序列
import java.util.*;
public class ac848 {
static HashMap<Integer, List<Integer>> map = new HashMap<>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[] iner = new int[n + 1];
while (m-- > 0) {
int a = sc.nextInt();
int b = sc.nextInt();
iner[b]++;
List<Integer> temp = map.getOrDefault(a, new ArrayList<>());
temp.add(b);
map.put(a, temp);
}
Queue<Integer> que = new LinkedList<>();
List<Integer> ans = new ArrayList<>();
boolean[] used = new boolean[n + 1];
boolean flag = false;
for (int i = 1; i <= n; i++) if (iner[i] == 0) que.offer(i);
while (!que.isEmpty()) {
int size=que.size();
List<Integer> temp=new ArrayList<>();
for(int i=0;i<size;i++){
int x=que.poll();
used[x]=true;
ans.add(x);
System.out.print(x+" ");
List<Integer> next=map.getOrDefault(x,new ArrayList<>());
for(int y:next){
iner[y]--;
if(iner[y]==0) temp.add(y);
}
}
System.out.println();
for(int x:temp) if(!used[x]) que.offer(x);
}
if(ans.size()!=n) System.out.println(-1);
else {
for(int x:ans) System.out.print(x+" ");
}
}
}