搜索算法刷题总结(DFS+BFS)

简介: 本文总结了DFS和BFS算法的基本模板及其典型应用。DFS部分包括指数型枚举、排列组合、N皇后问题等经典案例,展示了如何通过递归实现深度优先搜索。BFS部分涵盖了迷宫问题、马的遍历、洪水灌溉等场景,演示了使用队列实现广度优先搜索的方法。每种算法都提供了C++和Java的双语代码实现,包含状态标记、路径记录等关键步骤。文章还涉及剪枝优化、多源BFS等进阶技巧,为理解这两种基础搜索算法提供了全面参考。

 1.DFS

1.1 DFS基本模板

指数型枚举

https://www.acwing.com/problem/content/94/

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
const int N=17;
int n;
bool status[N];
void dfs(int x){
  if(x==n+1){
    for(int i=1;i<=n;i++){
      if(status[i]) cout<<i<<" ";
    }
    cout<<endl;
    return;
  }
  status[x]=true;
  dfs(x+1);
  status[x]=false;
  dfs(x+1); 
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0),cout.tie(0);
  cin>>n;
  dfs(1);
  return 0;
}

image.gif

import java.util.*;
public class Main {
    public static final int N=17;
    public static int n;
    public static boolean[] status=new boolean[N];
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n=sc.nextInt();
        dfs(1);
        
    }
    
    public static void dfs(int x){
        if(x==n+1){
            for(int i=1;i<=n;i++){
                if(status[i]) System.out.print(i+" ");
            }
            System.out.println();
            return;
        }
        status[x]=true;
        dfs(x+1);
        status[x]=false;
        dfs(x+1);
    }
    
}

image.gif

排列数字

https://www.acwing.com/problem/content/844/

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
const int N=10;
int arr[N];
bool status[N];
int n;
void dfs(int x){
  if(x==n+1){
    for(int i=1;i<=n;i++){
      cout<<arr[i]<<" ";
    }
    cout<<endl;
    return;
  }
  
  for(int i=1;i<=n;i++){
    if(!status[i]){
      arr[x]=i;
      status[i]=true;
      dfs(x+1);
      arr[x]=0;
      status[i]=false;
    }
  }
  
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0),cout.tie(0);
  cin>>n;
  dfs(1);
  return 0;
}

image.gif

import java.util.*;
public class Main {
    public static final int N=10;
    public static int n;
    public static int[] arr=new int[N];
    public static boolean[] status=new boolean[N];
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n=sc.nextInt();
        dfs(1);
    }
    
    public static void dfs(int x){
        if(x==n+1){
            for(int i=1;i<=n;i++){
                System.out.print(arr[i]+" ");
            }
            System.out.println();
            return;
        }
        for(int i=1;i<=n;i++){
            if(!status[i]){
                arr[x]=i;
                status[i]=true;
                dfs(x+1);
                arr[x]=0;
                status[i]=false;
            }
        }
        
    }
 
}

image.gif

组合数

https://www.luogu.com.cn/problem/P1157

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
const int N=24;
int n,r;
int arr[N];
void dfs(int x,int start){
  if(x==r+1){
    for(int i=1;i<=r;i++){
      printf("%3d",arr[i]);
    }
    cout<<endl;
    return;
  }
  for(int i=start;i<=n;i++){
    arr[x]=i;
    dfs(x+1,i+1);
    arr[x]=0;
  }
}
int main()
{
  scanf("%d%d",&n,&r);
  dfs(1,1);
  return 0;
}

image.gif

import java.util.*;
public class Main {
    public static final int N=24;
    public static int n,r;
    public static int[] arr=new int[N];
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n=sc.nextInt();
        r=sc.nextInt();
        dfs(1,1);
    }
    public static void dfs(int x,int start){
        if(x==r+1){
            for(int i=1;i<=r;i++){
                System.out.printf("%3d",arr[i]);
            }
            System.out.println();
            return;
        }
        for(int i=start;i<=n;i++){
            arr[x]=i;
            dfs(x+1,i+1);
            arr[x]=0;
        }
    }
}

image.gif

1.2 DFS习题

N皇后问题

https://www.acwing.com/problem/content/845/

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
const int N=11;
int n;
char graph[N][N];
bool col[N];
bool zuo[2*N+10];
bool you[2*N+10];
void dfs(int x){
  if(x==n){
    for(int i=0;i<n;i++){
      cout<<graph[i]<<endl;
    }
    cout<<endl;
    return;
  }
    
  for(int i=0;i<n;i++){
    if(!col[i] && !zuo[x+i] && !you[x-i+n]){
      graph[x][i]='Q'; 
      col[i]=zuo[x+i]=you[x-i+n]=true;
      dfs(x+1);
      col[i]=zuo[x+i]=you[x-i+n]=false;
      graph[x][i]='.';
    }
  }
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0),cout.tie(0);
  cin>>n;
  for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
      graph[i][j]='.';
    }
  }
  dfs(0);
  
  return 0;
}

image.gif

import java.util.*;
public class Main {
    public static final int N=12;
    public static int n;
    public static char[][] graph=new char[N][N];
    public static boolean[]col=new boolean[N];
    public static boolean[]zuo=new boolean[2*N+1];
    public static boolean[]you=new boolean[2*N+1];
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n=sc.nextInt();
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                graph[i][j]='.';
            }
        }
        dfs(0);
    }
    public static void dfs(int x){
        if(x==n){
            for(int i=0;i<n;i++){
                for(int j=0;j<n;j++){
                    System.out.print(graph[i][j]);
                }
                System.out.println();
            }
            System.out.println();
            return;
        }
        for(int i=0;i<n;i++){
            if(!col[i] && !zuo[x+i] && !you[x-i+n]){
                graph[x][i]='Q';
                col[i]=zuo[x+i]=you[x-i+n]=true;
                dfs(x+1);
                col[i]=zuo[x+i]=you[x-i+n]=false;
                graph[x][i]='.';
            }
        }
    }
}

image.gif

棋盘问题

https://www.acwing.com/problem/content/1116/

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
const int N=10;
int n,k;
char graph[N][N];
bool col[N];
int res;
void dfs(int x,int sum){
  if(sum==k){
    res++;
    return;
  }
  if(x==n) return;
  for(int i=0;i<n;i++){
    if(!col[i] && graph[x][i]=='#'){
      col[i]=true;
      dfs(x+1,sum+1);
      col[i]=false;
    }
  }
  
  dfs(x+1,sum);
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0),cout.tie(0);
  while(cin>>n>>k){
    if(n==-1 && k==-1) break;
    res=0;
    memset(col,false,sizeof(col));
    for(int i=0;i<n;i++){
      cin>>graph[i];
    }
    dfs(0,0);
    cout<<res<<endl;
  }
  
  
  return 0;
}

image.gif

import java.util.*;
public class Main {
    public static final int N=10;
    public static int n,k;
    public static char[][]graph=new char[N][N];
    public static boolean[] status=new boolean[N];
    public static int res;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while((n=sc.nextInt())!=-1 && (k=sc.nextInt())!=-1){
            res=0;
            Arrays.fill(status,false);
            for(int i=0;i<n;i++){
                String s=sc.next();
                for(int j=0;j<n;j++){
                    graph[i][j]=s.charAt(j);
                }
            }
            dfs(0,0);
            System.out.println(res);
        }
    }
    public static void dfs(int x,int sum){
        if(sum==k){
            res++;
            return;
        }
        if(x==n) return;
        for(int i=0;i<n;i++){
            if(!status[i] && graph[x][i]=='#'){
                status[i]=true;
                dfs(x+1,sum+1);
                status[i]=false;
            }
        }
        dfs(x+1,sum);
    }
}

image.gif

选数

https://www.luogu.com.cn/problem/P1036

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
const int N=25;
int n,k;
int arr[N];
int brr[N];
int res;
bool isPrime(int x){
  for(int i=2;i*i<=x;i++){
    if(x%i==0) return false;
  }
  return true;
}
void dfs(int x,int start){
  if(x==k+1){
    int sum=0;
    for(int i=1;i<=k;i++) sum+=brr[i];
    if(isPrime(sum)) res++;
    return;
  }
  
  for(int i=start;i<=n;i++){
    brr[x]=arr[i];
    dfs(x+1,i+1);
    brr[x]=0;
  }
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0),cout.tie(0); 
  cin>>n>>k;
  for(int i=1;i<=n;i++) cin>>arr[i];
  dfs(1,1);
  cout<<res<<endl;
  
  return 0;
}

image.gif

import java.util.*;
public class Main {
    public static final int N=25;
    public static int n,k,res;
    public static int[]arr=new int[N];
    public static int[]brr=new int[N];
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n=sc.nextInt();
        k=sc.nextInt();
        for(int i=1;i<=n;i++) arr[i]=sc.nextInt();
        dfs(1,1);
        System.out.println(res);
    }
    public static void dfs(int x,int start){
        if(x==k+1){
            int sum=0;
            for(int i=1;i<=k;i++) sum+=brr[i];
            if(isPrime(sum)) res++;
            return;
        }
        for(int i=start;i<=n;i++){
            brr[x]=arr[i];
            dfs(x+1,i+1);
            brr[x]=0;
        }
    }
    public static boolean isPrime(int x){
        for(int i=2;i*i<=x;i++){
            if(x%i==0) return false;
        }
        return true;
    }
}

image.gif

烧鸡

https://www.luogu.com.cn/problem/P2089

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
const int N=11;
const int M=1e5+10;
int n;
int arr[N];
int cnt;
int res[M][N];
void dfs(int x){
  if(x==11){
    int sum=0;
    for(int i=1;i<=10;i++){
      sum+=arr[i];
    }
    if(sum==n){
      cnt++;
      for(int i=1;i<=10;i++){
        res[cnt][i]=arr[i];
      }
      return;
    }
    return;
  }
  
  for(int i=1;i<=3;i++){
    arr[x]=i;
    dfs(x+1);
    arr[x]=0;
  }
  
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0),cout.tie(0);
  cin>>n;
  dfs(1);
  cout<<cnt<<endl;
  for(int i=1;i<=cnt;i++){
    for(int j=1;j<=10;j++){
      cout<<res[i][j]<<" ";
    }
    cout<<endl;
  } 
  
  return 0;
}

image.gif

import java.util.*;
public class Main {
    public static final int N=11;
    public static final int M= (int) (1e5+10);
    public static int n;
    public static int[]arr=new int[N];
    public static int cnt;
    public static int [][]res=new int[M][N];
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n=sc.nextInt();
        dfs(1);
        System.out.println(cnt);
        for(int i=1;i<=cnt;i++){
            for(int j=1;j<=10;j++){
                System.out.print(res[i][j]+" ");
            }
            System.out.println();
        }
    }
    public static void dfs(int x){
        if(x==11){
            int sum=0;
            for(int i=1;i<=10;i++) sum+=arr[i];
            if(sum==n){
                cnt++;
                for(int i=1;i<=10;i++) res[cnt][i]=arr[i];
                return;
            }
            return;
        }
        for(int i=1;i<=3;i++){
            arr[x]=i;
            dfs(x+1);
            arr[x]=0;
        }
    }
}

image.gif

PERKENT

https://www.luogu.com.cn/problem/P2036

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
const int MAX=0x3f3f3f3f;
const int N=15;
int n;
int s[N],b[N];
bool status[N];
int res=MAX;
void dfs(int x){
  if(x==n+1){
    int sum1=1,sum2=0;
    bool flag=false;
    for(int i=1;i<=n;i++){
      if(status[i]){
        sum1*=s[i];
        sum2+=b[i];
        flag=true;
      }
    }
    if(flag) res=min(res,abs(sum1-sum2));
    return;
  }
  
  status[x]=true;
  dfs(x+1);
  status[x]=false;
  dfs(x+1);
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0),cout.tie(0);
  cin>>n;
  for(int i=1;i<=n;i++){
    cin>>s[i]>>b[i];
  }
  dfs(1);
  cout<<res<<endl;
  
  return 0;
}

image.gif

import java.util.*;
public class Main {
    public static final int N=15;
    public static final int MAX=0x3f3f3f3f;
    public static int n;
    public static int []s=new int[N];
    public static int []b=new int[N];
    public static boolean []status=new boolean[N];
    public static int res=MAX;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n=sc.nextInt();
        for(int i=1;i<=n;i++){
            s[i]=sc.nextInt();
            b[i]=sc.nextInt();
        }
        dfs(1);
        System.out.println(res);
    }
    public static void dfs(int x){
        if(x==n+1){
            int sum1=1,sum2=0;
            boolean flag=false;
            for(int i=1;i<=n;i++){
                if(status[i]){
                    sum1*=s[i];
                    sum2+=b[i];
                    flag=true;
                }
            }
            if(flag){
                res=Math.min(res,Math.abs(sum2-sum1));
            }
            return;
        }
        status[x]=true;
        dfs(x+1);
        status[x]=false;
        dfs(x+1);
    }
}

image.gif

火星人

https://www.luogu.com.cn/problem/P1088

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m;
int arr[N];
int brr[N];
bool status[N];
int cnt;
bool flag;
void dfs(int x){
  if(flag) return;
  if(x==n+1){
    cnt++;
    if(cnt==m+1){
      flag=true;
      for(int i=1;i<=n;i++){
        cout<<brr[i]<<" ";
      }
      return;
    }
  }
  
  for(int i=1;i<=n;i++){
    if(cnt==0) i=arr[x];
    if(!status[i]){
      brr[x]=i;
      status[i]=true;
      dfs(x+1);
      brr[x]=0;
      status[i]=false;
    }
  }
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0),cout.tie(0);
  cin>>n>>m;
  for(int i=1;i<=n;i++){
    cin>>arr[i];
  }
  
  dfs(1);
  
  
  return 0;
}

image.gif

#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int arr[N]; // 存储排列,1基/0基均可,此处用0基适配STL
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> arr[i];
    }
    // 循环m次,求第m个后继排列
    for (int i = 0; i < m; i++) {
        // STL内置next_permutation:直接对数组进行修改,返回是否存在下一个排列
        // 题目保证结果不超出范围,因此无需判断返回值
        next_permutation(arr, arr + n);
    }
    for (int i = 0; i < n; i++) {
        cout<<arr[i]<<" "; 
    }
    return 0;
}

image.gif

import java.util.*;
public class Main {
    public static final int N= (int) (1e5+10);
    public static int n,m;
    public static int cnt;
    public static boolean flag;
    public static int []arr=new int[N];
    public static int []brr=new int[N];
    public static boolean[] status=new boolean[N];
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n=sc.nextInt();
        m=sc.nextInt();
        for(int i=1;i<=n;i++) arr[i]=sc.nextInt();
        dfs(1);
    }
    public static void dfs(int x){
        if(flag) return;
        if(x==n+1){
            cnt++;
            if(cnt==m+1){
                flag=true;
                for(int i=1;i<=n;i++){
                    System.out.print(brr[i]+" ");
                }
                return;
            }
            return;
        }
        for(int i=1;i<=n;i++){
            if(cnt==0) i=arr[x];
            if(!status[i]){
                brr[x]=i;
                status[i]=true;
                dfs(x+1);
                status[i]=false;
                brr[x]=0;
            }
        }
    }
}

image.gif

火柴棒等式

https://www.luogu.com.cn/problem/P1149

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int mode[N];
int n;
int arr[5];
int res;
void dfs(int x,int sum){
  if(sum>n) return;
  if(x==4){
    if(arr[1]+arr[2]==arr[3] && sum==n){
      res++;  
    }
    return;
  }
  
  for(int i=0;i<=1000;i++){
    arr[x]=i;
    dfs(x+1,sum+mode[i]);
    arr[x]=0;
  }
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0),cout.tie(0);
  mode[0]=6;
  mode[1]=2;
  mode[2]=5;
  mode[3]=5;
  mode[4]=4;
  mode[5]=5;
  mode[6]=6;
  mode[7]=3;
  mode[8]=7;
  mode[9]=6;
  cin>>n;
  n-=4;
  for(int i=10;i<=1000;i++){
    mode[i]=mode[i/10]+mode[i%10];
  }
  dfs(1,0); 
  cout<<res<<endl;
  
  return 0;
}

image.gif

import java.util.*;
public class Main {
    public static final int N= (int) (1e5+10);
    public static int n;
    public static int []mode=new int[N];
    public static int[] arr=new int[5];
    public static int res;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n=sc.nextInt();
        n-=4;
        mode[0]=6;
        mode[1]=2;
        mode[2]=5;
        mode[3]=5;
        mode[4]=4;
        mode[5]=5;
        mode[6]=6;
        mode[7]=3;
        mode[8]=7;
        mode[9]=6;
        for(int i=10;i<=1000;i++){
            mode[i]=mode[i/10]+mode[i%10];
        }
        dfs(1,0);
        System.out.println(res);
    }
    public static void dfs(int x,int sum){
        if(sum>n) return;
        if(x==4){
            if(arr[1]+arr[2]==arr[3] && sum==n){
                res++;
            }
            return;
        }
        for(int i=0;i<=1000;i++){
            arr[x]=i;
            dfs(x+1,sum+mode[i]);
            arr[x]=0;
        }
    }
}

image.gif

数的划分

https://www.luogu.com.cn/problem/P1025

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
const int N=220;
int n,k;
int arr[N];
int res;
void dfs(int x,int start,int sum){
  if(x==k+1){
    if(sum==n){
      res++;
    }
    return;
  }
  for(int i=start;i+sum<=n;i++){
    arr[x]=i;
    dfs(x+1,i,sum+i);
    arr[x]=0;
  }
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0),cout.tie(0);
  cin>>n>>k;
  dfs(1,1,0);
  cout<<res<<endl;
    
  return 0;
}

image.gif

import java.util.*;
public class Main {
    public static final int N=220;
    public static int n,k;
    public static int[]arr=new int[N];
    public static int res;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n=sc.nextInt();
        k=sc.nextInt();
        dfs(1,1,0);
        System.out.println(res);
    }
    public static void dfs(int x,int start,int sum){
        if(x==k+1){
            if(sum==n){
                res++;
            }
            return;
        }
        for(int i=start;i+sum<=n;i++){
            arr[x]=i;
            dfs(x+1,i,sum+i);
            arr[x]=0;
        }
    }
}

image.gif

2.BFS

1.1 BFS基本模板

入门

https://www.luogu.com.cn/problem/P1683

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII; 
const int N=25;
int w,h;
char graph[N][N];
bool status[N][N];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int res=1;
void bfs(int x,int y){
  queue<PII> q;
  q.push({x,y});
  while(q.size()){
    auto t=q.front();
    q.pop();
    for(int i=0;i<4;i++){
      x=t.first+dx[i];
      y=t.second+dy[i];
      if(x>=0 & x<h && y>=0 && y<w
      && !status[x][y] && graph[x][y]=='.'){
        status[x][y]=true;
        res++;
        q.push({x,y}); 
      }
    }
  }
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0),cout.tie(0);
  cin>>w>>h;
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      cin>>graph[i][j];
    }
  }
  
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if(graph[i][j]=='@'){
        bfs(i,j);
      }
    }
  }
  cout<<res<<endl;    
  
  return 0;
}

image.gif

import java.util.*;
class Node{
    int x,y;
    public Node(int x,int y){
        this.x=x;
        this.y=y;
    }
}
public class Main {
    public static final int N=25;
    public static int w,h;
    public static char[][] graph=new char[N][N];
    public static boolean[][] status=new boolean[N][N];
    public static int res=1;
    public static int dx[]={0,0,1,-1};
    public static int dy[]={1,-1,0,0};
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        w=sc.nextInt();
        h=sc.nextInt();
        for(int i=0;i<h;i++){
            String s=sc.next();
            for(int j=0;j<w;j++){
                graph[i][j]=s.charAt(j);
            }
        }
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                if(graph[i][j]=='@'){
                    bfs(i,j);
                }
            }
        }
        System.out.println(res);
    }
    public static void bfs(int x,int y){
        Queue<Node> q=new LinkedList<>();
        q.offer(new Node(x,y));
        while(!q.isEmpty()){
            Node node=q.poll();
            for(int i=0;i<4;i++){
                x=node.x+dx[i];
                y=node.y+dy[i];
                if(x>=0 && x<h && y>=0 && y<w && !status[x][y] && graph[x][y]=='.'){
                    res++;
                    status[x][y]=true;
                    q.offer(new Node(x,y));
                }
            }
        }
    }
}

image.gif

走迷宫

https://www.acwing.com/problem/content/846/

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=110;
int n,m;
int graph[N][N];
int dist[N][N];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
void bfs(){
  queue<PII> q;
  q.push({0,0});
  while(q.size()){
    auto t=q.front();
    q.pop();
    for(int i=0;i<4;i++){
      int x=t.first+dx[i];
      int y=t.second+dy[i];
      if(x>=0 && x<n & y>=0 && y<m
      && dist[x][y]==-1 && graph[x][y]==0){
        dist[x][y]=dist[t.first][t.second]+1;
        q.push({x,y});
      }
    }
  } 
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0),cout.tie(0);
  cin>>n>>m;
  for(int i=0;i<n;i++){
    for(int j=0;j<m;j++){
      cin>>graph[i][j];
    }
  }
  for(int i=0;i<n;i++){
    for(int j=0;j<m;j++){
      dist[i][j]=-1;
    }
  }
  dist[0][0]=0;
  bfs();  
  cout<<dist[n-1][m-1];
  
  return 0;
}

image.gif

import java.util.*;
class Node{
    int x,y;
    public Node(int x,int y){
        this.x=x;
        this.y=y;
    }
}
public class Main {
    public static final int N=110;
    public static int n,m;
    public static int[][]graph=new int[N][N];
    public static int[][]dist=new int[N][N];
    public static int dx[]={0,0,1,-1};
    public static int dy[]={1,-1,0,0};
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n=sc.nextInt();
        m=sc.nextInt();
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                graph[i][j]=sc.nextInt();
            }
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                dist[i][j]=-1;
            }
        }
        dist[0][0]=0;
        bfs();
        System.out.println(dist[n-1][m-1]);
    }
    public static void bfs(){
        Queue<Node> q=new LinkedList<>();
        q.offer(new Node(0,0));
        while (!q.isEmpty()){
            Node node=q.poll();
            for (int i = 0; i < 4; i++) {
                int x=node.x+dx[i];
                int y=node.y+dy[i];
                if(x>=0 && x<n && y>=0 && y<m
                && graph[x][y]==0 && dist[x][y]==-1){
                    dist[x][y]=dist[node.x][node.y]+1;
                    q.offer(new Node(x,y));
                }
            }
        }
    }
}

image.gif

洪水灌溉

https://www.luogu.com.cn/problem/P1596

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=110;
int n,m;
char graph[N][N];
bool status[N][N];
int dx[8]={1,1,0,0,-1,-1,1,-1};
int dy[8]={1,-1,1,-1,1,-1,0,0};
int res;
void bfs(int x,int y){
  queue<PII> q;
  q.push({x,y});
  while(q.size()){
    auto t=q.front();
    q.pop();
    for(int i=0;i<8;i++){
      x=t.first+dx[i];
      y=t.second+dy[i];
      if(x>=0 && x<n && y>=0 && y<m
      && !status[x][y] && graph[x][y]=='W'){
        status[x][y]=true;
        q.push({x,y});
      }
    }
  }
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0),cout.tie(0);
  cin>>n>>m;
  for(int i=0;i<n;i++){
    for(int j=0;j<m;j++){
      cin>>graph[i][j];
    }
  }
  
  for(int i=0;i<n;i++){
    for(int j=0;j<m;j++){
      if(graph[i][j]=='W' && !status[i][j]){
        status[i][j]=true;
        res++;
        bfs(i,j);
      }
    }
  }
  cout<<res<<endl;  
  
  
  return 0;
}

image.gif

import java.util.*;
class Node{
    int x,y;
    public Node(int x,int y){
        this.x=x;
        this.y=y;
    }
}
public class Main {
    public static final int N=110;
    public static int n,m,res;
    public static char[][] graph=new char[N][N];
    public static boolean[][] status=new boolean[N][N];
    public static int dx[]={0,0,1,-1,1,1,-1,-1};
    public static int dy[]={1,-1,0,0,-1,1,-1,1};
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n=sc.nextInt();
        m=sc.nextInt();
        for (int i = 0; i < n; i++) {
            String s=sc.next();
            for (int j = 0; j < m; j++) {
                graph[i][j]=s.charAt(j);
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if(graph[i][j]=='W' && !status[i][j]){
                    bfs(i,j);
                    res++;
                }
            }
        }
        System.out.println(res);
    }
    public static void bfs(int x,int y){
        Queue<Node> q=new LinkedList<>();
        q.offer(new Node(x,y));
        while (!q.isEmpty()){
            Node node = q.poll();
            for (int i = 0; i < 8; i++) {
                x=node.x+dx[i];
                y= node.y+dy[i];
                if(x>=0 && x<n && y>=0 && y<m && graph[x][y]=='W' && !status[x][y]){
                    status[x][y]=true;
                    q.offer(new Node(x,y));
                }
            }
        }
    }
}

image.gif

1.2 BFS习题

离开中山路

https://www.luogu.com.cn/problem/P1746

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=1010;
int a,b,c,d;
int graph[N][N];
int dist[N][N];
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
int n;
void bfs(){
  queue<PII> q;
  q.push({a,b});
  while(q.size()){
    auto t=q.front();
    q.pop();
    for(int i=0;i<4;i++){
      int x=t.first+dx[i];
      int y=t.second+dy[i];
      if(x>=1 && x<=n && y>=1 && y<=n
      && dist[x][y]==-1 && graph[x][y]==0){
        dist[x][y]=dist[t.first][t.second]+1;
        q.push({x,y});
      }
    }
  }
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0),cout.tie(0); 
  cin>>n;
  for(int i=1;i<=n;i++){
    string s;
    cin>>s;
    for(int j=1;j<=n;j++){
      graph[i][j]=s[j-1]-'0';
    }
  }
  
  cin>>a>>b>>c>>d;
  for(int i=1;i<=n;i++){
    for(int j=1;j<=n;j++){
      dist[i][j]=-1;
    }
  }
  
  dist[a][b]=0;
  bfs(); 
  cout<<dist[c][d]<<endl;
    
  return 0;
}

image.gif

import java.util.*;
class Node{
    int x,y;
    public Node(int x,int y){
        this.x=x;
        this.y=y;
    }
}
public class Main {
    public static final int N=1010;
    public static int n;
    public static int [][]graph=new int[N][N];
    public static int [][]dist=new int[N][N];
    public static int []dx={1,-1,0,0};
    public static int []dy={0,0,1,-1};
    public static int a,b,c,d;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n=sc.nextInt();
        for(int i=1;i<=n;i++){
            String s=sc.next();
            for(int j=1;j<=n;j++){
                graph[i][j]=s.charAt(j-1)-'0';
            }
        }
        a=sc.nextInt();
        b=sc.nextInt();
        c=sc.nextInt();
        d=sc.nextInt();
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                dist[i][j]=-1;
            }
        }
        dist[a][b]=0;
        bfs();
        System.out.println(dist[c][d]);
    }
    public static void bfs(){
        Queue<Node> q=new LinkedList<>();
        q.offer(new Node(a,b));
        while (!q.isEmpty()){
            Node node=q.poll();
            for(int i=0;i<4;i++){
                int x=node.x+dx[i];
                int y=node.y+dy[i];
                if(x>=1 && x<=n && y>=1 && y<=n
                && dist[x][y]==-1 && graph[x][y]==0){
                    dist[x][y]=dist[node.x][node.y]+1;
                    q.offer(new Node(x,y));
                }
            }
        }
    }
}

image.gif

马的遍历

https://www.luogu.com.cn/problem/P1443

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=420;
int n,m,x,y;
int dist[N][N];
int dx[8]={1,2,1,2,-1,-1,-2,-2};
int dy[8]={2,1,-2,-1,2,-2,1,-1};
void bfs(){
  queue<PII> q;
  q.push({x,y});
  while(q.size()){
    auto t=q.front();
    q.pop();
    for(int i=0;i<8;i++){
      x=t.first+dx[i];
      y=t.second+dy[i];
      if(x>=1 && x<=n && y>=1 && y<=m
      && dist[x][y]==-1){
        dist[x][y]=dist[t.first][t.second]+1;
        q.push({x,y});
      } 
    }
  }
  
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0),cout.tie(0);
  cin>>n>>m>>x>>y;
  for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++){
      dist[i][j]=-1;
    }
  } 
  dist[x][y]=0;
  bfs();
  for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++){
      cout<<dist[i][j]<<" "; 
    }
    cout<<endl;
  }
  
  
  return 0;
}

image.gif

import java.util.*;
class Node{
    int x,y;
    public Node(int x,int y){
        this.x=x;
        this.y=y;
    }
}
public class Main {
    public static final int N=410;
    public static int n,m,x,y;
    public static int[][]dist=new int[N][N];
    public static int []dx={1,2,1,2,-1,-1,-2,-2};
    public static int []dy={2,1,-2,-1,2,-2,1,-1};
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n=sc.nextInt();
        m=sc.nextInt();
        x=sc.nextInt();
        y=sc.nextInt();
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                dist[i][j]=-1;
            }
        }
        dist[x][y]=0;
        bfs();
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                System.out.print(dist[i][j]+" ");
            }
            System.out.println();
        }
    }
    public static void bfs(){
        Queue<Node> q=new LinkedList<>();
        q.offer(new Node(x,y));
        while (!q.isEmpty()){
            Node t=q.poll();
            for(int i=0;i<8;i++){
                x=t.x+dx[i];
                y=t.y+dy[i];
                if(x>=1 && x<=n && y>=1 && y<=m
                && dist[x][y]==-1){
                    dist[x][y]=dist[t.x][t.y]+1;
                    q.offer(new Node(x,y));
                }
            }
        }
    }
    
}

image.gif

血色先锋队

https://www.luogu.com.cn/problem/P1332

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=520;
int n,m,a,b;
int dist[N][N];
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
queue<PII> q;
void bfs(){
  while(q.size()){
    auto t=q.front();
    q.pop();
    for(int i=0;i<4;i++){
      int x=t.first+dx[i];
      int y=t.second+dy[i];
      if(x>=1 && x<=n && y>=1 && y<=m
      && dist[x][y]==-1){
        dist[x][y]=dist[t.first][t.second]+1;
        q.push({x,y});
      }
    }
  } 
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0),cout.tie(0);
  cin>>n>>m>>a>>b;
  for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++){
      dist[i][j]=-1;
    }
  } 
  
  for(int i=1;i<=a;i++){
    int x,y;
    cin>>x>>y;
    q.push({x,y});
    dist[x][y]=0;
  }
  bfs();
  for(int i=1;i<=b;i++){
    int x,y;
    cin>>x>>y;
    cout<<dist[x][y]<<endl;
  }
  
  
  
  
  return 0;
}

image.gif

import java.util.*;
class Node{
    int x,y;
    public Node(int x,int y){
        this.x=x;
        this.y=y;
    }
}
public class Main {
    public static final int N=520;
    public static int n,m,a,b;
    public static int[][]dist=new int[N][N];
    public static int []dx={0,0,1,-1};
    public static int []dy={1,-1,0,0};
    public static Queue<Node> q=new LinkedList<>();
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n=sc.nextInt();
        m=sc.nextInt();
        a=sc.nextInt();
        b=sc.nextInt();
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                dist[i][j]=-1;
            }
        }
        for(int i=1;i<=a;i++){
            int x,y;
            x=sc.nextInt();
            y=sc.nextInt();
            q.offer(new Node(x,y));
            dist[x][y]=0;
        }
        bfs();
        for(int i=1;i<=b;i++){
            int x,y;
            x=sc.nextInt();
            y=sc.nextInt();
            System.out.println(dist[x][y]);
        }
    }
    public static void bfs(){
        while(!q.isEmpty()){
            Node t=q.poll();
            for(int i=0;i<4;i++){
                int x=t.x+dx[i];
                int y=t.y+dy[i];
                if(x>=1 && x<=n && y>=1 && y<=m && dist[x][y]==-1){
                    dist[x][y]=dist[t.x][t.y]+1;
                    q.offer(new Node(x,y));
                }
            }
        }
    }
}

image.gif

填涂颜色

https://www.luogu.com.cn/problem/P1162

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=40;
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
int n;
int graph[N][N];
bool status[N][N];
void bfs(int x,int y){
  queue<PII> q;
  q.push({x,y});
  while(q.size()){
    auto t=q.front();
    q.pop();
    for(int i=0;i<4;i++){
      x=t.first+dx[i];
      y=t.second+dy[i];
      if(x>=0 && x<=n+1 && y>=0 && y<=n+1
      && !status[x][y] && graph[x][y]==0){
        status[x][y]=true;
        q.push({x,y});
      }
    }
  }
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0),cout.tie(0);
  cin>>n;
  for(int i=1;i<=n;i++){
    for(int j=1;j<=n;j++){
      cin>>graph[i][j];
    }
  }
  bfs(0,0);
  for(int i=1;i<=n;i++){
    for(int j=1;j<=n;j++){
      if(graph[i][j]==0 && !status[i][j]){
        graph[i][j]=2;
      }
    }
  }
  for(int i=1;i<=n;i++){
    for(int j=1;j<=n;j++){
      cout<<graph[i][j]<<" ";
    }
    cout<<endl;
  }
  
  return 0;
}

image.gif

import java.util.*;
class Node{
    int x,y;
    public Node(int x,int y){
        this.x=x;
        this.y=y;
    }
}
public class Main {
    public static final int N=35;
    public static int n;
    public static int [][]graph=new int[N][N];
    public static boolean[][] status=new boolean[N][N];
    public static int dx[]={0,0,1,-1};
    public static int dy[]={1,-1,0,0};
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                graph[i][j]=sc.nextInt();
            }
        }
        bfs(0,0);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(graph[i][j]==0 && !status[i][j]){
                    graph[i][j]=2;
                }
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                System.out.print(graph[i][j]+" ");
            }
            System.out.println();
        }
    }
    public static void bfs(int x,int y){
        Queue<Node> q=new LinkedList<>();
        q.offer(new Node(x,y));
        while (!q.isEmpty()){
            Node t=q.poll();
            for(int i=0;i<4;i++){
                x=t.x+dx[i];
                y=t.y+dy[i];
                if(x>=0 && x<=n+1 && y>=0 && y<=n+1
                        && !status[x][y] &&graph[x][y]==0){
                    status[x][y]=true;
                    q.offer(new Node(x,y));
                }
            }
        }
    }
}

image.gif

Meteor Shower S

https://www.luogu.com.cn/problem/P2895

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
const int MAX=0x3f3f3f3f;
typedef pair<int,int> PII;
const int N=320;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int dist[N][N];
int fire[N][N];
int m;
int bfs(){
  queue<PII> q;
  q.push({0,0});
  while(q.size()){
    auto t=q.front();
    q.pop();
    if(fire[t.first][t.second]==MAX){
      return dist[t.first][t.second];
    }
    for(int i=0;i<4;i++){
      int a=t.first+dx[i];
      int b=t.second+dy[i];
      if(a>=0 && b>=0 && fire[a][b]==MAX){
        return dist[t.first][t.second]+1;
      }
      if(a>=0 && b>=0 && dist[a][b]==MAX
      && dist[t.first][t.second]+1<fire[a][b]){
        dist[a][b]=dist[t.first][t.second]+1;
        q.push({a,b});
      }
    }
  }
  return -1;
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0),cout.tie(0);
  cin>>m;
  for(int i=0;i<N;i++){
    for(int j=0;j<N;j++){
      dist[i][j]=MAX;
      fire[i][j]=MAX;
    }
  }
  dist[0][0]=0;
  
  for(int i=1;i<=m;i++){
    int x,y,t;
    cin>>x>>y>>t;
    fire[x][y]=min(fire[x][y],t);
    for(int i=0;i<4;i++){
      int a=x+dx[i];
      int b=y+dy[i];
      if(a>=0 && b>=0) fire[a][b]=min(fire[a][b],t);
    }
  }
  int res=bfs();
  cout<<res<<endl;
    
  
  return 0;
}

image.gif

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
class Node{
    int x,y;
    public Node(int x,int y){
        this.x=x;
        this.y=y;
    }
}
public class Main {
    public static final int MAX=0x3f3f3f3f;
    public static final int N=320;
    public static int m;
    public static int[] dx={0,0,1,-1};
    public static int[] dy={1,-1,0,0};
    public static int[][] fire=new int[N][N];
    public static int[][] dist=new int[N][N];
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        m=sc.nextInt();
        for(int i=0;i<N;i++){
            for(int j=0;j<N;j++){
                fire[i][j]=MAX;
                dist[i][j]=MAX;
            }
        }
        dist[0][0]=0;
        for(int i=1;i<=m;i++){
            int x,y,t;
            x=sc.nextInt();
            y=sc.nextInt();
            t=sc.nextInt();
            fire[x][y]=Math.min(fire[x][y],t);
            for(int j=0;j<4;j++){
                int a=x+dx[j];
                int b=y+dy[j];
                if(a>=0 && b>=0){
                    fire[a][b]=Math.min(fire[a][b],t);
                }
            }
        }
        int res=bfs();
        System.out.println(res);
    }
    public static int bfs() {
        Queue<Node> q=new LinkedList<>();
        q.offer(new Node(0,0));
        while(!q.isEmpty()){
            Node t=q.poll();
            if(fire[t.x][t.y]==MAX){
                return dist[t.x][t.y];
            }
            for(int i=0;i<4;i++){
                int a=t.x+dx[i];
                int b=t.y+dy[i];
                if(a>=0 && b>=0 && fire[a][b]==MAX){
                    return dist[t.x][t.y]+1;
                }
                if(a>=0 && b>=0 && dist[a][b]==MAX && dist[t.x][t.y]+1<fire[a][b]){
                    dist[a][b]=dist[t.x][t.y]+1;
                    q.offer(new Node(a,b));
                }
            }
        }
        return -1;
    }
}

image.gif

八数码

https://www.acwing.com/problem/content/847/

代码模板(C++/Java):

#include<bits/stdc++.h>
using namespace std;
const int N=10;
typedef pair<int,int> PII;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int n,m;
int bfs(string s){
  queue<string> q;
  unordered_map<string,int> d;
  q.push(s);
  d[s]=0;
  string end="12345678x";
  while(q.size()){
    auto t=q.front();
    q.pop();
    if(t==end) return d[t];
    int distance=d[t];
    int k=t.find('x');
    int x=k/3,y=k%3;
    for(int i=0;i<4;i++){
      int a=x+dx[i],b=y+dy[i];
      if(a>=0 && a<3 && b>=0 && b<3){
        swap(t[a*3+b],t[k]);
        if(!d.count(t)){
          d[t]=distance+1;
          q.push(t);
        }
        swap(t[a*3+b],t[k]);
      }
    }
  }
  return -1;
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  char c[2];
  string s;
  for(int i=0;i<9;i++){
    cin>>c;
    s+=c;
  }
  cout<<bfs(s)<<endl;
  return 0;
}

image.gif

import java.util.*;
public class Main {
    public static Queue<String> q=new LinkedList<>();
    public static Map<String,Integer> map=new HashMap<>();
    public static int[]dx={0,0,1,-1};
    public static int[]dy={1,-1,0,0};
    public static String target="12345678x";
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        StringBuilder sb=new StringBuilder();
        for (int i = 0; i < 9; i++) {
            String s=sc.next();
            sb.append(s);
        }
        int res=bfs(sb.toString());
        System.out.println(res);
    }
    public static int bfs(String s){
        q.add(s);
        map.put(s,0);
        while (!q.isEmpty()){
            String cur=q.poll();
            int d=map.get(cur);
            if(cur.equals(target)){
                return map.get(cur);
            }
            int k=cur.indexOf("x");
            int x=k/3;
            int y=k%3;
            for (int i = 0; i < 4; i++) {
                int a=x+dx[i];
                int b=y+dy[i];
                if(a>=0 && a<3 && b>=0 && b<3){
                    char[]arr=cur.toCharArray();
                    char t=arr[k];
                    arr[k]=arr[a*3+b];
                    arr[a*3+b]=t;
                    String str=new String(arr);
                    if(!map.containsKey(str)){
                        q.add(str);
                        map.put(str,d+1);
                    }
                }
            }
        }
        return -1;
    }
}

image.gif

相关文章
|
4天前
|
人工智能 JSON 机器人
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
本文带你零成本玩转OpenClaw:学生认证白嫖6个月阿里云服务器,手把手配置飞书机器人、接入免费/高性价比AI模型(NVIDIA/通义),并打造微信公众号“全自动分身”——实时抓热榜、AI选题拆解、一键发布草稿,5分钟完成热点→文章全流程!
10597 53
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
|
10天前
|
人工智能 JavaScript API
解放双手!OpenClaw Agent Browser全攻略(阿里云+本地部署+免费API+网页自动化场景落地)
“让AI聊聊天、写代码不难,难的是让它自己打开网页、填表单、查数据”——2026年,无数OpenClaw用户被这个痛点困扰。参考文章直击核心:当AI只能“纸上谈兵”,无法实际操控浏览器,就永远成不了真正的“数字员工”。而Agent Browser技能的出现,彻底打破了这一壁垒——它给OpenClaw装上“上网的手和眼睛”,让AI能像真人一样打开网页、点击按钮、填写表单、提取数据,24小时不间断完成网页自动化任务。
2422 5
|
24天前
|
人工智能 JavaScript Ubuntu
5分钟上手龙虾AI!OpenClaw部署(阿里云+本地)+ 免费多模型配置保姆级教程(MiniMax、Claude、阿里云百炼)
OpenClaw(昵称“龙虾AI”)作为2026年热门的开源个人AI助手,由PSPDFKit创始人Peter Steinberger开发,核心优势在于“真正执行任务”——不仅能聊天互动,还能自动处理邮件、管理日程、订机票、写代码等,且所有数据本地处理,隐私完全可控。它支持接入MiniMax、Claude、GPT等多类大模型,兼容微信、Telegram、飞书等主流聊天工具,搭配100+可扩展技能,成为兼顾实用性与隐私性的AI工具首选。
24075 122
|
4天前
|
人工智能 IDE API
2026年国内 Codex 安装教程和使用教程:GPT-5.4 完整指南
Codex已进化为AI编程智能体,不仅能补全代码,更能理解项目、自动重构、执行任务。本文详解国内安装、GPT-5.4接入、cc-switch中转配置及实战开发流程,助你从零掌握“描述需求→AI实现”的新一代工程范式。(239字)
2369 126

热门文章

最新文章