【蓝桥杯】双指针、BFS和图论

双指针:把i,j两层for循环转换为以下形式:
 

import java.util.*;
import java.io.*;

class Main{
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));

        int N = 100010;

        String[] a = bf.readLine().split(" ");

        int n = Integer.parseInt(a[0]);
        int d = Integer.parseInt(a[1]);
        int k = Integer.parseInt(a[2]);

        int[] cnt = new int[N];
        boolean[] std = new boolean[N];
        List<int[]> list = new ArrayList<>();

        int maxid = 0;

        for (int i = 0; i < n; i++) {
            String[] temp1 = bf.readLine().split(" ");
            int ts = Integer.parseInt(temp1[0]);
            int id = Integer.parseInt(temp1[1]);

            int[] temp = {ts,id};

            list.add(temp);

            
            maxid = Math.max(maxid,id);
        }

        list.sort((o1, o2) -> {
            return o1[0] - o2[0];
        });

        for (int i = 0 , j = 0; i < n; i++) { // i 表示时间节点的尾部
            int id = list.get(i)[1];

            cnt[id]++; // 在时间段内,编号为i的帖子出现了几次 || 将时间段结尾的帖子加入

            while (list.get(i)[0] - list.get(j)[0] >= d){ // 当时间段大于给定期限
                cnt[list.get(j)[1]]--; // 将时间段开头的帖子去掉一个赞,因为该赞不属于这个时间段了
                j++; // 时间节点的头部向后移位
            }

            if (cnt[id] >= k) std[id] = true;
        }

        for (int i = 0; i <= maxid; i++) {
            if (std[i] == true){
                pw.println(i);
                pw.flush();
            }
        }

    }
}

栈:递归:dfs

队列:bfs:

每次取出队头元素,将拓展的元素放到队尾

import java.util.*;
import java.io.*;

class Main{
    static int N = 210;
    static int n = 0; // 行
    static int m = 0; // 列

    static char[][] g = new char[N][N]; // 地图
    static int[][] dist = new int[N][N]; // 表示起点到某点的距离

    public static int bfs(List<Integer> start,List<Integer> end){
        Queue<List<Integer>> queue = new LinkedList<>();
        
        for (int i = 0; i < N; i++){
            for (int j = 0; j < N; j++){
                dist[i][j] = -1;
            }
        }

        dist[start.get(0)][start.get(1)] = 0; // 到起点的距离为0
        queue.add(start);

        int[] dx = {-1,0,1,0} , dy = {0,1,0,-1};// 设置偏移量

        while (queue.size() > 0){
            List<Integer> poll = queue.poll();

            for (int i = 0; i < 4; i++) {
                int x = poll.get(0) + dx[i];
                int y = poll.get(1) + dy[i];

                if (x < 0 || x >= n || y < 0 || y >= m) continue;
                if (g[x][y] == '#') continue; // 遇见障碍物
                if (dist[x][y] != -1) continue; // 已经走过了

                dist[x][y] = dist[poll.get(0)][poll.get(1)] + 1;

                if (end.get(0) == x && end.get(1) == y) return dist[x][y];

                List<Integer> temp = new ArrayList<>();
                temp.add(x);temp.add(y);
                queue.add(temp);
            }
        }
        return -1;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));

        int T = Integer.parseInt(bf.readLine());
        while (T-- > 0){
            String[] temp = bf.readLine().split(" ");
            n = Integer.parseInt(temp[0]);
            m = Integer.parseInt(temp[1]);

            for (int i = 0; i < n; i++) g[i] = bf.readLine().toCharArray();

            List<Integer> start = new ArrayList<>();
            List<Integer> end = new ArrayList<>();

            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    if (g[i][j] == 'S'){
                        start.add(i);
                        start.add(j);
                    }else if (g[i][j] == 'E'){
                        end.add(i);
                        end.add(j);
                    }
                }
            }

            int distance = bfs(start,end);
            if (distance == -1) System.out.println("oop!");
            else System.out.println(distance);
        }


    }

}

2的d-1次方 ==  (1 << (d-1))

import java.util.*;

class Main{
    
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        
        int N = 100010;
        int[] a = new int[N];
        
        int n = sc.nextInt();
        
        for (int i = 1; i <= n; i++){
            a[i] = sc.nextInt();
        }
        
        int depth = 0;
        long max = Long.MIN_VALUE;
        
        for (int d = 1 , i = 1; i <= n; d++, i *= 2) { // d代表层数 , i代表该层起点 
            long s = 0;
            
            for (int j = i; j < i + (1 << d-1) && j <= n; j++){ // j代表该层的元素下标
                s += a[j];
            
            }
            
            if (s > max){ // 结算
                max = s;
                depth = d;
            }
        }
        
        System.out.print(depth);
    }
    
}

三维的偏移量

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main{
    static int N = 110;
    static int L;
    static int R;
    static int C;
    static PIIs start;
    static PIIs end;
    static char[][][] g = new char[N][N][N];
    static int[][][] dist = new int[N][N][N];
    static int[] dx = new int[] {1,-1,0,0,0,0};
    static int[] dy = new int[] {0,0,1,-1,0,0};
    static int[] dz = new int[] {0,0,0,0,1,-1};
    static int bfs()
    {
        Queue<PIIs> q = new LinkedList<PIIs>();
        q.add(start);

        for(int i = 0;i < L;i++)
            for(int j = 0;j < R;j++)
                Arrays.fill(dist[i][j], -1);

        dist[start.x][start.y][start.z] = 0;

        while(!q.isEmpty())
        {
            PIIs t = q.poll();

            for(int i = 0;i < 6;i++)
            {
                int a = t.x + dx[i];
                int b = t.y + dy[i];
                int c = t.z + dz[i];
                if(a < 0 || a >= L || b < 0 || b >= R || c < 0 || c >= C) continue;
                if(g[a][b][c] == '#') continue;
                if(dist[a][b][c] != -1) continue;

                dist[a][b][c] = dist[t.x][t.y][t.z] + 1;
                if(a == end.x && b == end.y && c == end.z) return dist[a][b][c];
                q.add(new PIIs(a,b,c));
            }
        }
        return -1;
    }
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        while(scan.hasNext())
        {
            L = scan.nextInt();
            R = scan.nextInt();
            C = scan.nextInt();
            if(L == 0 && R == 0 && C == 0) break;
            for(int i = 0;i < L;i ++)
            {
                for(int j = 0;j < R;j ++)
                {
                    char[] charArray = scan.next().toCharArray();
                    for(int k = 0;k < C;k ++)
                    {
                        g[i][j][k] = charArray[k];
                        if(g[i][j][k] == 'S') start = new PIIs(i,j,k);
                        if(g[i][j][k] == 'E') end = new PIIs(i,j,k);
                    }
                }
            }
            int distance = bfs();
            if(distance == -1) System.out.println("Trapped!");
            else System.out.println("Escaped in " + distance + " minute(s).");
        }
    }
}
class PIIs
{
    public int x;//第x层
    public int y;//第y行
    public int z;//第z列
    public PIIs(int x,int y,int z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }
}

 

import java.util.*;
import java.io.*;

class Main{

    static int N = 1010;
    static char[][] g = new char[N][N];
    static boolean[][] st = new boolean[N][N];

    static int total = 0;
    static int bound = 0;
    static int n = 0;

    static int[] dx = {-1,0,1,0} , dy = {0,1,0,-1};

    public static void bfs(int sx,int sy){
        Queue<Point> queue = new LinkedList<>();
        queue.add(new Point(sx,sy));

        st[sx][sy] = true;

        while (!queue.isEmpty()){
            Point poll = queue.poll();
            total++;

            boolean is_bound = false;
            for (int i = 0; i < 4; i++) {
                int x = poll.x + dx[i] , y = poll.y + dy[i];

                if ( x < 0 || x >= n || y < 0 || y >= n) continue; // 出界
                if ( st[x][y]) continue; // 去重
                if ( g[x][y] == '.'){
                    is_bound = true;
                    continue;
                }

                queue.add(new Point(x,y));
                st[x][y] = true;
            }

            if (is_bound) bound++;
        }

    }

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));

        n = Integer.parseInt(bf.readLine());

        for (int i = 0; i < n; i++) {
            char[] temp = bf.readLine().toCharArray();
            for (int j = 0; j < n; j++) {
                g[i][j] = temp[j];
            }
        }

        int res = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (!st[i][j] && g[i][j] == '#'){
                    total = 0;
                    bound = 0;
                    bfs(i,j);
                    if (total == bound) res++;
                }
            }    
        }
        
        
        System.out.print(res);
    }

}

class Point{
    int x , y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

当岛屿总数与被淹没数相等时,就可以完全沉没

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值