第九届蓝桥杯大赛个人赛省赛(软件类)真题

记不住月份?记住这个2741数即可
转为二进制后有12位,0是小月,1是大月

第几天

2000年的1月1日,是那一年的第1天。
那么,2000年的5月4日,是那一年的第几天?
125

class MC {
    int[] dm = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
    boolean is29(int year){
        return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
    }
    public void run() {
        int cnt = 0;
        int y = 2000, m = 5, d = 4;
        if (is29(y)) dm[2] = 29;
        for (int i = 1; i <= m - 1; i++) {
            cnt += dm[i];
        }
        cnt += d;
        System.out.println(cnt);
    }
}
public class Main {
    public static void main(String[] args) {
        new MC().run();
    }
}

方格计数

在这里插入图片描述
算出第一象限的小方格的数后乘4

import java.io.*;
class MC{
    /**
     * 题目并不仅是叫你数1x1的小方格,还有2x2,3x3,...,nxn的小方格
     * 就坑人
     */
    public void run() throws IOException {
        long r = 1000;
        long cnt = 0;
        //枚举每个小方格的右下角起点(x,y)
        for (int i = 1; i < r; i++) {
            for (int j = 1; j < r; j++) {
               if (i *i +j *j <= r *r) cnt++;
            }
        }
        System.out.println(cnt * 4);
    }
    int toInt(String s){
        return Integer.parseInt(s);
    }
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
}
public class Main {
    public static void main(String[] args) throws IOException {
        new MC().run();
    }
}

负数幂

在这里插入图片描述

在这里插入图片描述

import java.io.*;
import java.math.BigInteger;
class MC{
    /**
     * (a+bi)(c+di)=(ac-bd)+(bc+ad)i
     */
    public void run() throws IOException {
        BigInteger a = BigInteger.valueOf(2);
        BigInteger b = BigInteger.valueOf(3);
        BigInteger c = BigInteger.valueOf(2);
        BigInteger d = BigInteger.valueOf(3);
        int cnt = 123456;
        for (int i = 2; i <= cnt; i++) {
            BigInteger t = a;
            a = a.multiply(c).subtract(b.multiply(d));
            b = b.multiply(c).add(t.multiply(d));
        }
        if (b.compareTo(new BigInteger("0")) >= 0) System.out.printf("%s+%si", a, b);
        else System.out.printf("%s%si", a, b);
    }

    int toInt(String s){
        return Integer.parseInt(s);
    }
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
}

public class Main {
    public static void main(String[] args) throws IOException {
        new MC().run();
    }
}

测试次数

在这里插入图片描述
跟着大佬走

import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;

class MC {

    int N = (int) (1e4 + 10);
    int n;
    //f[i][j] 还有i个手机,j层待测楼的所有方案的集合中所需测试次数最小的方案
    int[][] f = new int[4][N];

    public void run() {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();

        //只有1个手机,只能一层一层试,最多试楼层的次数
        for (int i = 1; i <= 3; i++) {
            for (int j = 0; j <= n; j++) {
                //最多试j次
                f[i][j] = j;
            }
        }

        //当前手机数
        for (int i = 2; i <= 3; i++) {
            //当前最大楼层数
            for (int j = 1; j <= n; j++) {
                //有了最大楼层数,还需知道要从哪一楼往下扔
                //若手机在k层丢下去损坏,说明在[k, j]楼丢手机都一定损坏,手机数-1.搜索区间变为[1, k - 1],
                //若手机在k层丢下去没有损坏,手机数不变, 说明在[1, k]楼丢手机都不会损坏,搜索区间变为[k + 1, j],测试的次数加1
                for (int k = 1; k <= j; k++) {
                    f[i][j] = Math.min(f[i][j], Math.max(f[i - 1][(k-1) - 1 + 1], f[i][j - (k+1) + 1]) + 1);
                }
            }
        }

        System.out.println(f[3][n]);
    }
}

public class Main {
    public static void main(String[] args) {
        new MC().run();
    }
}

递增三元组

在这里插入图片描述

跟着大佬走

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

class MC {

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    int N = (int) (1e5 + 10);
    int[] a = new int[N], b = new int[N], c = new int[N];
    int n;

    void handleInput(int[] t, String s){
        String[] ss = s.split(" ");
        for (int i = 1; i <= ss.length; i++) {
            t[i] = Integer.parseInt(ss[i - 1]);
        }
    }

    int fl(int[] h, int x){
        int l = 0 , r = n + 1;
        while (l < r){
            int mid = l + r >> 1;
            if(h[mid] >= x) r = mid; else l = mid + 1;
        }
        return l;
    }

    int fr(int[] h, int x){
        int l = 0 , r = n + 1;
        while (l < r){
            int mid = l + r + 1>> 1;
            if(h[mid] <= x) l = mid; else r = mid - 1;
        }
        return l;
    }



    public void run() throws IOException {
        n = Integer.parseInt(br.readLine());
        handleInput(a, br.readLine());handleInput(b, br.readLine());handleInput(c, br.readLine());
        Arrays.sort(a,1,n + 1);
        Arrays.sort(b,1,n + 1);
        Arrays.sort(c,1,n + 1);

        long res = 0;
        for (int i = 1; i <= n; i++) {
            int x = fl(a, b[i]);
            int y = fr(c, b[i]);
            if (x == 0 || y == n + 1) continue;
            res += (long) (x - 1) * (n - y);
        }
        System.out.println(res);
    }
}
public class Main {
    public static void main(String[] args) throws IOException {
        new MC().run();
    }
}

螺旋折线

在这里插入图片描述

在这里插入图片描述
找规律+模拟
这应该可以用二分优化,以后再搞把
规律:从原点出发,向左走d,再向上走d,d+1;,向右走d,再向下走d,d+1;如此反复
因此,第p圈的各个值已经确定了,如calculate函数所示

import java.io.IOException;
import java.util.Scanner;

class MC {

    /**
     * 模拟:左上d+1,右下d+1
     *
     */
    long N = (long) (1e9 + 10);
    long d = 1,  x = 0, y = 0;
    //从原点到(x,y)的距离
    long dist = 0;
    long tx, ty;
    long ans;

    boolean cx(){
        //y相同,不管y
        if (ty != y) return false;
        if (Math.abs(x) < Math.abs(tx)) return false;
        if (x < 0){
            if(tx <= 0){
                ans = dist - (tx - x);
            }else ans = dist - (-x + tx);
        }else {
            if(tx <= 0){
                ans = dist - (-tx + x);
            }else ans = dist - (x - tx);
        }
        return true;
    }

    boolean cy(){
        //相同,不管x
        if (tx != x) return false;
        if (Math.abs(y) < Math.abs(ty)) return false;
        if (y < 0){
            if(ty <= 0){
                ans = dist - (ty - y);
            }else ans = dist - (-y + ty);
        }else {
            if(ty <= 0){
                ans = dist - (-ty + y);
            }else ans = dist - (y - ty);
        }
        return true;
    }

    void calculate(long p){
        long m = 2 * p;
        x = p;
        y = -p;
        d = d + 2 * p;
        dist = d * m;
//        System.out.println(x + " " + y + " " + d + " " + dist);
    }

    boolean handle(){
        //往左
        x -= d;
        dist += d;
        if (cx()) return true;
        //往上
        y += d;
        dist += d;
        if (cy()) return true;
        d++;
        //往右
        x += d;
        dist += d;
        if (cx()) return true;
        //往下
        y -= d;
        dist += d;
        if (cy()) return true;
        d++;
        return false;
    }

    public void run() throws IOException {
        Scanner sc = new Scanner(System.in);
        tx = sc.nextInt();
        ty = sc.nextInt();
        //先确定tx,ty在哪圈
        calculate((Math.abs(tx)+ Math.abs(ty)) / 2);
        while (!handle()){
        }
        System.out.println(ans);
    }
}

public class Main {
    public static void main(String[] args) throws IOException {
        new MC().run();
    }
}

日志统计

在这里插入图片描述
在这里插入图片描述
参考

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

class MC {

    int N = (int) (1e5 + 10000 +  10);
    int n, d, k;
    int[] cnt = new int[N];
    boolean[] st = new boolean[N];
    int[][] logs = new int[N][2];

    public void run() throws IOException {
        String[] ss = br.readLine().split(" ");
        n = toInt(ss[0]); d = toInt(ss[1]); k = toInt(ss[2]);
        for (int i = 0; i < n; i++) {
            ss = br.readLine().split(" ");
            logs[i][0] = toInt(ss[0]);
            logs[i][1] = toInt(ss[1]);
        }
        Arrays.sort(logs, 0, n, (o1, o2) -> o1[0] - o2[0]);

        for (int i = 0, j = 0; i < n; i++) {
            int id = logs[i][1];
            cnt[id]++;
            while (logs[i][0]- logs[j][0] >= d){
                cnt[logs[j][1]]--;
                j++;
            }
            if (cnt[id] >= k) st[id] = true;
        }

        for (int i = 0; i < N; i++) {
            if (st[i]) System.out.println(i);
        }
    }

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    int toInt(String s){return Integer.parseInt(s);}
}

public class Main {
    public static void main(String[] args) throws IOException {
        new MC().run();
    }
}

全球变暖

在这里插入图片描述

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

class MC {
    int N = (int) (1e3 + 10);
    int[][] g = new int[N][N];
    int[][] fx = new int[][]{{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
    boolean[][] st = new boolean[N][N];
    int n;
    int res = 0;

    public void run() throws IOException {
        n = toInt(br.readLine());
        for (int i = 1; i <= n; i++) {
            String s = br.readLine();
            for (int j = 1; j <= n; j++) {
                if(s.charAt(j - 1) == '#') g[i][j] = 1;
            }
        }
        
        //遍历地图
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                //如果当前不是陆地,或者已被访问过,就继续循环
                if (g[i][j] == 0 || st[i][j]) continue;
                //被访问过,标记一下
                st[i][j] = true;
                //处理以该点开始的连通块,并判断该连通块会不会沉没
                handle(i, j);
            }
        }
        System.out.println(res);
    }

    //找连通块并判断此联通块会不会沉没
    private void handle(int i, int j) {
        //bfs遍历连通块
        Queue<int[]> q = new LinkedList<>();
        q.add(new int[]{i, j});
        //判断该连通块会不会沉没
        boolean f = true;
        while (q.size() > 0){
            int[] p = q.poll();
            int x = p[0], y = p[1];
            //该点的四周是陆地的个数
            int cnt = 0;
            for (int k = 0; k < 4; k++) {
                int tx = x + fx[k][0], ty = y + fx[k][1];
                //不用判断边界
                if (g[tx][ty] == 0) continue;
                //周围有块陆地
                cnt++;
                if (st[tx][ty]) continue;
                st[tx][ty] = true;
                q.add(new int[]{tx, ty});
            }
            //若该点周围有4块陆地,该连通块不会沉没
            if (cnt == 4) f = false;
        }
        //若没有一个点的周围都是陆地,该连通块沉没
        if(f) res++;
    }

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    int toInt(String s){return Integer.parseInt(s);}
}

public class Main {
    public static void main(String[] args) throws IOException {
        new MC().run();
    }
}

堆的计数

在这里插入代码片
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值