Java算法:牛客网网易笔试真题算法Java版1-81题

题号	题目	知识点	难度	通过率
WY1	奖学金	动态规划模拟	较难	12.84%
WY2	路灯	动态规划	较难	14.22%
WY3	小易的升级之路	递归模拟	简单	20.03%
WY4	炮台攻击		简单	18.14%
WY5	扫描透镜	贪心模拟穷举	较难	15.89%
WY6	合唱团	动态规划	较难	14.33%
WY7	地牢逃脱	队列	简单	17.68%
WY8	下厨房	字符串	入门	34.60%
WY9	分田地	动态规划	中等	15.98%
WY10	分苹果	贪心	入门	23.24%
WY11	星际穿越		入门	22.45%
WY12	藏宝图	字符串动态规划	入门	29.40%
WY13	数列还原	穷举	入门	28.29%
WY14	混合颜料	贪心	中等	19.77%
WY15	幸运的袋子	穷举	中等	18.28%
WY16	不要二	贪心	入门	31.89%
WY17	解救小易	排序	入门	37.25%
WY18	统计回文	字符串模拟穷举	入门	30.61%
WY19	饥饿的小易	数学	中等	17.28%
WY20	两种排序方法	排序字符串	入门	25.74%
WY21	小易喜欢的单词	字符串	入门	33.88%
WY22	Fibonacci数列	模拟	入门	36.00%
WY23	数字游戏	排序	入门	26.94%
WY24	洗牌	排序模拟穷举	简单	18.19%
WY25	构造队列	模拟队列	入门	30.20%
WY26	回文序列	贪心模拟	入门	23.90%
WY27	优雅的点	计算几何	入门	16.57%
WY28	跳石板	动态规划贪心	中等	14.40%
WY29	暗黑的字符串	动态规划	入门	24.79%
WY30	数字翻转	模拟	入门	35.38%
WY31	最大的奇约数	模拟穷举	中等	12.31%
WY32	买苹果	贪心动态规划	入门	32.79%
WY33	计算糖果	穷举	入门	28.65%
WY34	彩色的砖块	字符串模拟	中等	27.28%
WY35	等差数列	贪心排序	中等	27.09%
WY36	交错01串	字符串	中等	27.70%
WY37	操作序列	模拟队列	中等	16.57%
WY38	独立的小易	贪心模拟	中等	28.98%
WY39	堆棋子	模拟	中等	17.93%
WY40	疯狂队列	贪心	中等	22.08%
WY41	小易喜欢的数列	动态规划	中等	19.22%
WY42	时钟	字符串模拟	中等	23.00%
WY43	字符迷阵	字符串模拟	中等	29.76%
WY44	会话列表	模拟栈	中等	33.87%
WY45	牛牛找工作	排序贪心模拟	中等	10.00%
WY46	被3整除	数学	简单	14.33%
WY47	安置路灯	字符串数组模拟贪心	简单	27.06%
WY48	迷路的牛牛	字符串模拟	入门	31.09%
WY49	数对	数学	简单	13.75%
WY50	矩形重叠	穷举	简单	22.02%
WY51	牛牛的闹钟		入门	24.32%
WY52	牛牛的背包问题	穷举	中等	15.12%
WY53	一封奇怪的信	字符串模拟	入门	25.12%
WY54	糖果谜题	贪心模拟哈希	中等	25.02%
WY55	最小众倍数	递归穷举	简单	29.90%
WY56	缩写	字符串模拟	简单	47.81%
WY57	工作方案	数学	较难	20.75%
WY58	数位重排	数组模拟穷举	中等	38.32%
WY59	数轴	贪心模拟	中等	24.85%
WY60	骰子游戏	动态规划	较难	21.25%
WY61	俄罗斯方块	数组模拟贪心	入门	30.59%
WY62	瞌睡	数组贪心	简单	14.78%
WY63	丰收	数组	简单	17.48%
WY64	整理房间	模拟穷举	中等	29.27%
WY65	表达式求值	动态规划	入门	42.67%
WY66	塔	排序贪心模拟	简单	22.04%
WY67	小易的字典		中等	16.81%
WY68	代价	排序穷举	入门	42.30%
WY69	访友	贪心	入门	44.24%
WY70	翻转翻转		简单	11.66%
WY71	买房	贪心	简单	28.09%
WY72	香槟塔	数组	较难	24.35%
WY73	社团主席选举	排序贪心模拟穷举	中等	18.58%
WY74	橡皮泥斑马	字符串模拟	简单	34.37%
WY75	篮球队	递归动态规划穷举	中等	18.01%
WY76	字母卡片	排序字符串贪心	简单	16.62%
WY77	相等序列	排序贪心穷举数组	简单	24.79%
WY78	N-GCD	动态规划	中等	20.82%
WY79	分贝壳		简单	21.73%
WY80	美妙的约会	排序动态规划贪心	入门	34.23%
WY81	模数求和	数学	入门	40.85%

WY1 奖学金

题目描述

小v今年有n门课,每门都有考试,为了拿到奖学金,小v必须让自己的平均成绩至少为avg。每门课由平时成绩和考试成绩组成,满分为r。现在他知道每门课的平时成绩为ai ,若想让这门课的考试成绩多拿一分的话,小v要花bi
的时间复习,不复习的话当然就是0分。同时我们显然可以发现复习得再多也不会拿到超过满分的分数。为了拿到奖学金,小v至少要花多少时间复习。

输入描述:

第一行三个整数n,r,avg(n大于等于1小于等于1e5,r大于等于1小于等于1e9,avg大于等于1小于等于1e6),接下来n行,每行两个整数ai和bi,均小于等于1e6大于等于1

输出描述:

一行输出答案。

示例1
输入
5 10 9 0 5 9 1 8 1 0 1 9 100
输出
43
import java.util.*;
import java.io.*;

//贪心
public class Main {
   
    public static void main(String[] args) throws Exception {
   
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str;
        while ((str = bf.readLine()) != null) {
   
            String[] strs = str.split(" ");
            int n = Integer.parseInt(strs[0]);  //科目数
            int r = Integer.parseInt(strs[1]);  //每科满分
            int avg = Integer.parseInt(strs[2]);  //达标的平均成绩
            int cur_total = 0;
            Queue<Course> prQue = new PriorityQueue<>();
            for (int i = 0; i < n; i++) {
   
                String[] strs2 = bf.readLine().split(" ");
                Course temp = new Course(Integer.parseInt(strs2[0]), Integer.parseInt(strs2[1]));
                prQue.add(temp);
                cur_total += Integer.parseInt(strs2[0]);
            }
            long res = func(n, r, avg, cur_total, prQue);
            System.out.println(res);
        }
    }

    public static long func(int n, int r, int avg, int cur_total, Queue<Course> prQue) {
   
        long res = 0;
        while (cur_total < n * avg) {
   
            int gap = n * avg - cur_total;
            Course top = prQue.poll();
            if (gap > r - top.a_score) {
   
                res += (long) top.b_time * (r - top.a_score);
                cur_total += r - top.a_score;
            } else {
   
                res += (long) top.b_time * gap;
                cur_total += gap;
            }
        }
        return res;
    }
}

class Course implements Comparable<Course> {
   
    int a_score;
    int b_time;

    public Course(int a_score, int b_time) {
   
        this.a_score = a_score;
        this.b_time = b_time;
    }

    @Override
    public int compareTo(Course o) {
   
        if (this.b_time > o.b_time) return 1;
        else return -1;
    }
}

WY2 路灯

题目描述

一条长l的笔直的街道上有n个路灯,若这条街的起点为0,终点为l,第i个路灯坐标为ai ,每盏灯可以覆盖到的最远距离为d,为了照明需求,所有灯的灯光必须覆盖整条街,但是为了省电,要使这个d最小,请找到这个最小的d。

输入描述:

每组数据第一行两个整数n和l(n大于0小于等于1000,l小于等于1000000000大于0)。第二行有n个整数(均大于等于0小于等于l),为每盏灯的坐标,多个路灯可以在同一点。

输出描述:

输出答案,保留两位小数。

示例1
输入
7 15 15 5 3 7 9 14 0
输出
2.50
import java.util.*;
import java.io.*;

public class Main {
   
    public static void main(String[] args) throws IOException {
   
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String line;
        int[] pos;
        while ((line = reader.readLine()) != null) {
   
            String[] temp = line.split(" ");
            int n = Integer.parseInt(temp[0]);
            int l = Integer.parseInt(temp[1]);
            line = reader.readLine();
            temp = line.split(" ");
            pos = new int[n];
            for (int i = 0; i < n; i++) {
   
                pos[i] = Integer.parseInt(temp[i]);
            }
            Arrays.sort(pos);
            double max_gap = Math.max(pos[0], l - pos[n - 1]);
            for (int i = 0; i < n - 1; i++) {
   
                double gap = (pos[i + 1] - pos[i]) / 2.0;
                max_gap = Math.max(gap, max_gap);
            }
            // double ans = max_gap / 2.0;
            System.out.printf("%.2f%n", max_gap);
        }
    }
}

WY3 小易的升级之路

题目描述

小易经常沉迷于网络游戏.有一次,他在玩一个打怪升级的游戏,他的角色的初始能力值为 a.在接下来的一段时间内,他将会依次遇见n个怪物,每个怪物的防御力为b1,b2,b3…bn.
如果遇到的怪物防御力bi小于等于小易的当前能力值c,那么他就能轻松打败怪物,并 且使得自己的能力值增加bi;如果bi大于c,那他也能打败怪物,但他的能力值只能增加bi
与c的最大公约数.那么问题来了,在一系列的锻炼后,小易的最终能力值为多少?

输入描述:

对于每组数据,第一行是两个整数n(1≤n<100000)表示怪物的数量和a表示小易的初始能力值. 第二行n个整数,b1,b2…bn(1≤bi≤n)表示每个怪物的防御力

输出描述:

对于每组数据,输出一行.每行仅包含一个整数,表示小易的最终能力值

示例1
输入
3 50 50 105 200 5 20 30 20 15 40 100
输出
110 205
import java.util.*;
import java.io.*;

public class Main {
   
    public static void main(String[] args) throws IOException {
   
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str;
        while ((str = br.readLine()) != null) {
   
            String[] s = str.split(" ");
            int n = Integer.parseInt(s[0]);
            int c = Integer.parseInt(s[1]);
            int[] b = new int[n];
            for (int i = 0; i < n; i++) {
   
                str = br.readLine();
                b[i] = Integer.parseInt(str);
                if (b[i] <= c) {
   
                    c += b[i];
                } else {
   
                    c += getGCD(b[i], c);
                }
            }
            System.out.println(c);
        }
    }

    public static int getGCD(int a, int b) {
      //a>b
        while (b != 0) {
   
            int temp = b;
            b = a % b;
            a = temp;
        }
        return a;
    }
}

WY4 炮台攻击

题目描述

兰博教训提莫之后,然后和提莫讨论起约德尔人,谈起约德尔人,自然少不了一个人,那 就是黑默丁格------约德尔人历史上最伟大的科学家. 提莫说,黑默丁格最近在思考一个问题:黑默丁格有三个炮台,炮台能攻击到距离它R的敌人 (
两点之间的距离为两点连续的距离,例如(3,0),(0,4)之间的距离是5),如果一个炮台能攻击 到敌人,那么就会对敌人造成1×的伤害.黑默丁格将三个炮台放在N*M方格中的点上,并且给出敌人 的坐标. 问:那么敌人受到伤害会是多大?

输入描述:

第一行9个整数,R,x1,y1,x2,y2,x3,y3,x0,y0.R代表炮台攻击的最大距离,(x1,y1),(x2,y2), (x3,y3)代表三个炮台的坐标.(x0,y0)代表敌人的坐标.

输出描述:

输出一行,这一行代表敌人承受的最大伤害,(如果每个炮台都不能攻击到敌人,输出0×)

示例1
输入
1 1 1 2 2 3 3 1 2
输出
2x
import java.util.*;
import java.io.*;

public class Main {
   
    public static void main(String[] args) throws IOException {
   
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        while ((str = br.readLine()) != null) {
   
            String[] t = str.split(" ");
            int r = Integer.parseInt(t[0]);
            int x1 = Integer.parseInt(t[1]);
            int y1 = Integer.parseInt(t[2]);
            int x2 = Integer.parseInt(t[3]);
            int y2 = Integer.parseInt(t[4]);
            int x3 = Integer.parseInt(t[5]);
            int y3 = Integer.parseInt(t[6]);
            int x0 = Integer.parseInt(t[7]);
            int y0 = Integer.parseInt(t[8]);
            int cnt = 0;
            if (Math.pow((x1 - x0), 2) + Math.pow((y1 - y0), 2) <= r * r) {
   
                cnt++;
            }
            if (Math.pow((x2 - x0), 2) + Math.pow((y2 - y0), 2) <= r * r) {
   
                cnt++;
            }
            if (Math.pow((x3 - x0), 2) + Math.pow((y3 - y0), 2) <= r * r) {
   
                cnt++;
            }
            System.out.println(cnt + "x");
        }
    }
}

WY5 扫描透镜

题目描述

在NM的草地上,提莫种了K个蘑菇,蘑菇爆炸的威力极大,兰博不想贸然去闯,而且蘑菇是隐形的.只 有一种叫做扫描透镜的物品可以扫描出隐形的蘑菇,于是他回了一趟战争学院,买了2个扫描透镜,一个 扫描透镜可以扫描出(33)
方格中所有的蘑菇,然后兰博就可以清理掉一些隐形的蘑菇. 问:兰博最多可以清理多少个蘑菇? 注意:每个方格被扫描一次只能清除掉一个蘑菇。

输入描述:

第一行三个整数:N,M,K,(1≤N,M≤20,K≤100),N,M代表了草地的大小; 接下来K行,每行两个整数x,y(1≤x≤N,1≤y≤M).代表(x,y)处提莫种了一个蘑菇. 一个方格可以种无穷个蘑菇.

输出描述:

输出一行,在这一行输出一个整数,代表兰博最多可以清理多少个蘑菇.

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

public class Main {
   
    public static int[][] sudoku = {
   {
   -1, -1}, {
   0, -1}, {
   0, 1}, {
   1, -1}, {
   1, 1}, {
   -1, 0}, {
   1, 0}, {
   -1, 1}};

    public static int clearMushroom(int[][] mushroom) {
   
        int max = 0;
        int maxI = 0;
        int maxJ = 0;
        for (int i = 1; i < mushroom.length - 1; i++) {
   
            for (int j = 1; j < mushroom[0].length - 1; j++) {
   
                int tmp = 0;
                if (mushroom[i][j] > 0) {
   
                    tmp += 1;
                }
                for (int k = 0; k < 8; k++) {
   
                    if (mushroom[i + sudoku[k][0]][j + sudoku[k][1]] > 0)
                        tmp += 1;
                }
                if (tmp > max) {
   
                    max = tmp;
                    maxI = i;
                    maxJ = j;
                }
            }
        }
        mushroom[maxI][maxJ] -= 1;
        for (int k = 0; k < 8; k++) {
   
            mushroom[maxI + sudoku[k][0]][maxJ + sudoku[k][1]] -= 1;
        }
        return max;
    }

    public static void main(String[] args) throws Exception {
   
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str;
        while ((str = br.readLine()) != null) {
   
            String[] strs = str.split(" ");
            int N = Integer.parseInt(strs[0]);
            int M = Integer.parseInt(strs[1]);
            int K = Integer.parseInt(strs[2]);
            int[][] mushroom = new int[N][M];
            int x;
            int y;
            for (int i = 0; i < K; i++) {
   
                str = br.readLine();
                strs = str.split(" ");
                x = Integer.parseInt(strs[0]) - 1;
                y = Integer.parseInt(strs[1]) - 1;
                mushroom[x][y] += 1;
            }
            System.out.println(clearMushroom(mushroom) + clearMushroom(mushroom));
        }
    }
}

WY6 合唱团

题目描述

有 n 个学生站成一排,每个学生有一个能力值,牛牛想从这 n 个学生中按照顺序选取 k 名学生,要求相邻两个学生的位置编号的差不超过 d,使得这 k 个学生的能力值的乘积最大,你能返回最大的乘积吗?

输入描述:

每个输入包含 1 个测试用例。每个测试数据的第一行包含一个整数 n (1 <= n <= 50),表示学生的个数,接下来的一行,包含 n 个整数,按顺序表示每个学生的能力值 ai(-50 <= ai <=
50)。接下来的一行包含两个整数,k 和 d (1 <= k <= 10, 1 <= d <= 50)。

输出描述:

输出一行表示最大的乘积。

示例1
输入
3 7 4 7 2 50
输出
49
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main {
   
    public static void main(String[] args) throws Exception {
   
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line;
        while ((line = br.readLine()) != null) {
   
            int n = Integer.parseInt(line.trim());
            line = br.readLine();
            int[] nums = new int[n];
            String[] s = line.trim().split(" ");
            for (int i = 0; i < n; i++) {
   
                nums[i] = Integer.parseInt(s[i]);  //a[i]表示学生的能力值
            }
            line = br.readLine();
            String[] s1 = line.trim().split(" ");
            int k = Integer.parseInt(s1[0]);  //选取k个学生
            int d = Integer.parseInt(s1[1]);  //编号之差不超过d
            long[][] max = new long[k][n];
            long[][] min = new long[k][n];
            for (int i = 0; i < k; i++) {
   
                for (int j = 0; j < n; j++) {
   
                    max[i][j] = 1;
                    min[i][j] = 1;
                    if (i == 0) {
   
                        min[i][j] = nums[j];
                        max[i][j] = nums[j];
                    }
                }
            }
            for (int i = 1; i < k; i++) {
   
                for (int j = 0; j < n; j++) {
   
                    for (int m = 1; m <= d; m++) {
   
                        if (j - m >= 0) {
   
                            if (nums[j] > 0) {
   
                                min[i][j] = Math.min(min[i][j], min[i - 1][j - m] * nums[j]);
                                max[i][j] = Math.max(max[i][j], max[i - 1][j - m] * nums[j]);
                            } else {
   
                                min[i][j] = Math.min(min[i][j], max[i - 1][j - m] * nums[j]);
                                max[i][j] = Math.max(max[i][j], min[i - 1][j - m] * nums[j]);
                            }
                        }
                    }
                }
            }
            long res = 0;
            for (int i = 0; i < n; i++) {
   
                if (i >= k - 1) {
   
                    res = Math.max(res, max[k - 1][i]);
                }
            }
            System.out.println(res);
        }
    }
}

WY7 地牢逃脱

题目描述

给定一个 n 行 m 列的地牢,其中 ‘.’ 表示可以通行的位置,‘X’ 表示不可通行的障碍,牛牛从 (x0 , y0 )
位置出发,遍历这个地牢,和一般的游戏所不同的是,他每一步只能按照一些指定的步长遍历地牢,要求每一步都不可以超过地牢的边界,也不能到达障碍上。地牢的出口可能在任意某个可以通行的位置上。牛牛想知道最坏情况下,他需要多少步才可以离开这个地牢。

输入描述:

每个输入包含 1 个测试用例。每个测试用例的第一行包含两个整数 n 和 m(1 <= n, m <= 50),表示地牢的长和宽。接下来的 n 行,每行 m 个字符,描述地牢,地牢将至少包含两个 ‘.’。接下来的一行,包含两个整数 x0,
y0,表示牛牛的出发位置(0 <= x0 < n, 0 <= y0 < m,左上角的坐标为 (0, 0),出发位置一定是 ‘.’)。之后的一行包含一个整数 k(0 < k <= 50)表示牛牛合法的步长数,接下来的 k 行,每行两个整数
dx, dy 表示每次可选择移动的行和列步长(-50 <= dx, dy <= 50)

输出描述:

输出一行一个数字表示最坏情况下需要多少次移动可以离开地牢,如果永远无法离开,输出 -1。以下测试用例中,牛牛可以上下左右移动,在所有可通行的位置.上,地牢出口如果被设置在右下角,牛牛想离开需要移动的次数最多,为3次。

示例1
输入
3 3 ... ... ... 0 1 4 1 0 0 1 -1 0 0 -1
输出
3
import java.util.*;

public class Main {
   
    public static void main(String[] args) {
   
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
   
            //注意while处理多个case
            int x = in.nextInt();
            int y = in.nextInt();
            char[][] points = new char[x][y];
            int[][] tar = new int[x][y];
            for (int i = 0; i < x; i++) {
   
                String str = in.next();
                points[i] = str.toCharArray();
            }
            int startx = in.nextInt();
            int starty = in.nextInt();
            int k = in.nextInt();
            int[] stepx = new int[k];
            int[] stepy = new int[k];
            for (int i = 0; i < k; i++) {
   
                stepx[i] = in.nextInt();
                stepy[i] = in.nextInt();
            }
            Queue<Integer> xqueue = new LinkedList<Integer>();
            Queue<Integer> yqueue = new LinkedList<Integer>();
            //引入队列是为了遍历到最后不能走为止
            xqueue.add(startx);
            yqueue.add(starty);
            tar[startx][starty] = 1;  //起始点访问标记;1表示已经访问
            while (!xqueue.isEmpty() && !yqueue.isEmpty()) {
   
                startx = xqueue.remove();    //取队首
                starty = yqueue.remove();
                for (int i = 0; i < k; i++) {
   
                    if (startx + stepx[i] < x && startx + stepx[i] >= 0 && starty + stepy[i] < y && starty + stepy[i] >= 0)   //不出界
                        if (tar[startx + stepx[i]][starty + stepy[i]] == 0) {
   
                            if (points[startx + stepx[i]][starty + stepy[i]] == '.') {
   
                                tar[startx + stepx[i]][starty + stepy[i]] = tar[startx][starty] + 1;
                                xqueue.add(startx + stepx[i]);
                                yqueue.add(starty + stepy[i]);
                            } else
                                tar[startx + stepx[i]][starty + stepy[i]] = -1;  //访问点为X
                        }
                }
            }
            int max = 0;
            int getRoad = 1;
            for (int i = 0; i < x; i++)
                for (int j = 0; j < y; j++) {
   
                    if (points[i][j] == '.' && tar[i][j] == 0) {
   
                        getRoad = 0;   //有存在没有被访问的“.”说明不能遍历完全,有些出口到不了。
                    }
                    max = Math.max(max, tar[i][j]);
                }
            if (getRoad == 0)
                System.out.println(-1);
            else
                System.out.println(max - 1);
        }
    }
}

WY8 下厨房

题目描述

牛牛想尝试一些新的料理,每个料理需要一些不同的材料,问完成所有的料理需要准备多少种不同的材料。

输入描述:

每个输入包含 1 个测试用例。每个测试用例的第 i 行,表示完成第 i 件料理需要哪些材料,各个材料用空格隔开,输入只包含大写英文字母和空格,输入文件不超过 50 行,每一行不超过 50 个字符。

输出描述:

输出一行一个数字表示完成所有料理需要多少种不同的材料。

示例1
输入
BUTTER FLOUR HONEY FLOUR EGG
输出
4
import java.util.*;
import java.io.*;

public class Main {
   
    public static void main(String[] args)
            throws IOException {
   
        HashSet<String> set = new HashSet<>();
        BufferedReader rd = new BufferedReader(new InputStreamReader(System.in));
        String str = rd.readLine();
        while (str != null) {
   
            String[] arr = str.trim().split(" ");
            set.addAll(Arrays.asList(arr));
            str = rd.readLine();
        }
        System.out.println(set.size());
    }
}

WY9 分田地

题目描述

牛牛和 15 个朋友来玩打土豪分田地的游戏,牛牛决定让你来分田地,地主的田地可以看成是一个矩形,每个位置有一个价值。分割田地的方法是横竖各切三刀,分成 16 份,作为领导干部,牛牛总是会选择其中总价值最小的一份田地,
作为牛牛最好的朋友,你希望牛牛取得的田地的价值和尽可能大,你知道这个值最大可以是多少吗?

输入描述:

每个输入包含 1 个测试用例。每个测试用例的第一行包含两个整数 n 和 m(1 <= n, m <= 75),表示田地的大小,接下来的 n 行,每行包含 m 个 0-9 之间的数字,表示每块位置的价值。

输出描述:

输出一行表示牛牛所能取得的最大的价值。

示例1
输入
4 4 3332 3233 3332 2323
输出
2
import java.util.*;

public class Main {
   
    static int n;
    static int m;
    static int[][] data;

    public static void main(String[] args) {
   
        Scanner scan = new Scanner(System.in);
        while (scan.hasNext()) {
   
            n = scan.nextInt();
            m = scan.nextInt();
            data = new int[n + 1][m + 1];
            for (int i = 1; i <= n; i++) {
   
                String str = scan.next();
                char[] strchar = str.toCharArray();
                for (int j = 1; j <= m; j++) {
   
                    data[i][j] = strchar[j - 1] - '0';
                }
            }
            for (int i = 1; i <= n; i++) {
   
                for (int j = 1; j <= m; j++) {
   
                    data[i][j] = data[i - 1][j] + data[i][j - 1] - data[i - 1][j - 1] + data[i][j];
                }
            }
            int l = 0;
            int r = data[n][m];
            int mid = r = (l + r) >> 3;
            int res = 0;
            while (l <= r) {
   
                mid = (l + r) >> 1;
                if (check(mid)) {
   
                    l = mid + 1;
                    res = mid;
                } else {
   
                    r = mid - 1;
                }
            }
            System.out.println(res);
        }
    }

    private static boolean check(int mid) {
   
        for (int i = 1; i <= n - 3; i++) {
   
            for (int j = i + 1; j <= n - 2; j++) {
   
                for (int k = j + 1; k <= n - 1; k++) {
   
                    int last = 0;
                    int count = 0;
                    for (int h = 1; h <= m; h++) {
   
                        int sum1 = getSum(0, i, last, h);
                        int sum2 = getSum(i, j, last, h);
                        int sum3 = getSum(j, k, last, h);
                        int sum4 = getSum(k, n, last, h);
                        if (mid <= sum1 && mid <= sum2 && mid <= sum3 && mid <= sum4) {
   
                            last = h;
                            count++;
                        }
                    }
                    if (count >= 4) {
   
                        return true;
                    }
                }
            }
        }
        return false;
    }

    private static int getSum(int startx, int x, int starty, int y) {
   
        return data[x][y] - data[startx][y] - data[x][starty] + data[startx][starty];
    }
}

WY10 分苹果

题目描述

n 只奶牛坐在一排,每个奶牛拥有 ai 个苹果,现在你要在它们之间转移苹果,使得最后所有奶牛拥有的苹果数都相同,每一次,你只能从一只奶牛身上拿走恰好两个苹果到另一个奶牛上,问最少需要移动多少次可以平分苹果,如果方案不存在输出 -1。

输入描述:

每个输入包含一个测试用例。每个测试用例的第一行包含一个整数 n(1 <= n <= 100),接下来的一行包含 n 个整数 ai(1 <= ai <= 100)。

输出描述:

输出一行表示最少需要移动多少次可以平分苹果,如果方案不存在则输出 -1。

示例1
输入
4 7 15 9 5
输出
3
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main {
   
    public static void main(String[] args) throws Exception {
   
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = null;
        while ((line = br.readLine()) != null) {
   
            int n = Integer.parseInt(line);
            int[] a = new int[n];
            line = br.readLine();
            String[] s = line.trim().split(" ");
            for (int i = 0; i < n; i++) {
   
                a[i] = Integer.parseInt(s[i]);
            }
            int sum = 0;
            for (int i = 0; i < n; i++) {
   
                sum += a[i];
            }
            if (sum % n != 0) {
   
                System.out.println(-1);
                return;
            }
            int avg = sum / n;
            for (int i = 0; i < n; i++) {
   
                if (Math.abs(a[i] - avg) % 2 != 0) {
   
                    System.out.println(-1);
                    return;
                }
            }
            int count = 0;
            for (int i = 0; i < n; i++) {
   
                if (a[i] < avg) {
   
                    count += (avg - a[i]) / 2;
                }
            }
            System.out.println(count);
        }
    }
}

WY11 星际穿越

题目描述

航天飞行器是一项复杂而又精密的仪器,飞行器的损耗主要集中在发射和降落的过程,科学家根据实验数据估计,如果在发射过程中,产生了 x 程度的损耗,那么在降落的过程中就会产生 x2
程度的损耗,如果飞船的总损耗超过了它的耐久度,飞行器就会爆炸坠毁。问一艘耐久度为 h 的飞行器,假设在飞行过程中不产生损耗,那么为了保证其可以安全的到达目的地,只考虑整数解,至多发射过程中可以承受多少程度的损耗?

输入描述:

每个输入包含一个测试用例。每个测试用例包含一行一个整数 h (1 <= h <= 10^18)。

输出描述:

输出一行一个整数表示结果。

示例1
输入
10
输出
2
import java.io.*;

public class Main {
   
    public static void main(String[] args) throws IOException {
   
        BufferedReader reder = new BufferedReader(new InputStreamReader(System.in));
        String str = reder.readLine();
        long h = Long.parseLong(str);
        long x = (long) (-1 + Math.sqrt(1 + 4 * h)) / 2;
        System.out.println(x);
    }
}

WY12 藏宝图

题目描述

牛牛拿到了一个藏宝图,顺着藏宝图的指示,牛牛发现了一个藏宝盒,藏宝盒上有一个机关,机关每次会显示两个字符串 s 和 t,根据古老的传说,牛牛需要每次都回答 t 是否是 s 的子序列。注意,子序列不要求在原字符串中是连续的,例如串
abc,它的子序列就有 {空串, a, b, c, ab, ac, bc, abc} 8 种。

输入描述:

每个输入包含一个测试用例。每个测试用例包含两行长度不超过 10 的不包含空格的可见 ASCII 字符串。

输出描述:

输出一行 “Yes” 或者 “No” 表示结果。

示例1
输入
x.nowcoder.com ooo
输出
Yes
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main {
   
    public static void main(String[] args) throws Exception {
   
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s1 = br.readLine();
        String s2 = br.readLine();
        char[] brr = s2.toCharArray();
        String result = "Yes";
        for (char c : brr) {
   
            int m = s1.indexOf(c);
            if (m != -1) {
   
                s1 = s1.substring(m + 1);
                continue;
            }
            result = "No";
        }
        System.out.println(result);
    }
}

WY13 数列还原

题目描述

牛牛的作业薄上有一个长度为 n 的排列 A,这个排列包含了从1到n的n个数,但是因为一些原因,其中有一些位置(不超过 10 个)看不清了,但是牛牛记得这个数列顺序对的数量是 k,顺序对是指满足 i < j 且 A[i] < A[j]
的对数,请帮助牛牛计算出,符合这个要求的合法排列的数目。

输入描述:

每个输入包含一个测试用例。每个测试用例的第一行包含两个整数 n 和 k(1 <= n <= 100, 0 <= k <= 1000000000),接下来的 1 行,包含 n 个数字表示排列 A,其中等于0的项表示看不清的位置(不超过 10
个)。

输出描述:

输出一行表示合法的排列数目。

示例1
输入
5 5 4 0 0 2 0
输出
2
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {
   
    //全排列
    public static void prem(List<List<Integer>> prem, List<Integer> temp, List<Integer> num) {
   
        if (temp.size() == num.size()) {
   
            prem.add(new ArrayList<>(temp));
        } else {
   
            for (int i = 0; i < num.size(); i++) {
   
                if (temp.contains(num.get(i))) continue;
                temp.add(num.get(i));
                prem(prem, temp, num);
                temp.remove(temp.size() - 1);
            }
        }
    }

    //统计丢失数据的顺序对,和丢失数据和原有数据的顺序对
    public static int calculate(List<Integer> list, int[] array) {
   
        int val = 0;
        int j = 0;
        for (int i = 0; i < array.length; i++) {
   
            if (array[i] == 0) {
   
                array[i] = list.get(j++);
                for (int k = 0; k < i; k++) {
   
                    if (array[k] != 0 && array[k] < array[i]) {
   
                        val++;
                    }
                }
                for (int k = i + 1; k < array.length; k++) {
   
                    if (array[k] != 0 && array[k] > array[i]) {
   
                        val++;
                    }
                }
            }
        }
        return val;
    }

    public static void main(String[] args) throws Exception 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值