考试时间: 2023-09-16 (2小时)      T1   小美正在参加比赛,一共有 n 场比赛,赢得一场可以获得 1 分,如果上一场也赢了,可以获得额外的 1 分。现在给你 n 场比赛的结果,你需要计算小美的分数。   输入描述   第一行一个整数n,表示比赛的场数。 下一行n个整数,表示每场比赛的结果,1 表示赢,0 表示输。 1 ≤ n ≤    输出描述   一个整数,表示小美的分数。   示例   输入:51 1 1 0 1输出:6说明:第一场比赛获胜,获得1分。第二场比赛获胜,并且上场比赛也获胜,获得2分。第三次比赛获胜,并且上场比赛也获胜,获得2分。第四场比赛输了,获得0分。第五场比赛获胜,获得1分。   题解   import java.util.Scanner;// P1public class Main {    public static void main(String[] args) {        Scanner in = new Scanner(System.in);        int n = in.nextInt();        int[] a = new int[n];        for (int i = 0; i < n; i++) a[i] = in.nextInt();        int score = a[0];        for (int i = 1; i < n; i++) {            if (a[i] == 1) {                score += (a[i - 1] == 1) ? 2 : 1;            }        }        System.out.println(score);    }}   T2   小美在训练场打靶,靶一共有 10 环,靶的中心位于 (0,0),如果打中的位置在以靶心为圆心,半径为 1 的圆内,则得 10 分,之后每向外一圈分数减 1,直到 1 分,每圈的半径都比上一圈大 1。即如果打中的位置在以靶心为圆心,半径为i的圆内,则得 11 - i 分。   如果打中的位置不在任何一圈内,则得 0分。   输入描述   一行两个整数 x,y,表示打中的位置坐标。   1 ≤ x,y ≤ 10   输出描述   输出一个整数,表示得分。   示例1   输入:1 0输出:10   示例2   输入:1 1输出:9   题解   import java.util.Scanner;public class Main {    public static void main(String[] args) {        Scanner in = new Scanner(System.in);        int x = in.nextInt(), y = in.nextInt();        int dd = x * x + y * y;        // 特别容易遗漏        int res = dd == 0 ? 11 : 0;        for (int i = 1; i < 12; i++) {            if (dd <= i * i) {                res = 11 - i;                break;            }        }        System.out.println(res);    }}   T3   小美在玩游戏,游戏中有 n 个怪物,怪物的血量为 , 攻击力为 , 小美的血量为H,攻击力为A, 小美可以击败血量和攻击力都小于自己的怪物,并且打败怪物后血量降为怪物的血量,攻击力降为怪物的攻击力,小美想知道最多可以打败多少怪物。   输入描述   第一行三个整数 n,H,A,分别表示怪物的数量,小美的血量,小美的攻击。   第二行n个整数 , 表示怪物的血量。   第三行n个整数 ,表示怪物的攻击力。   1 ≤ n ≤       输出描述   输出一个整数表示答案。   示例1   输入:3 4 51 2 33 2 1输出:1说明:最多只能击败一个怪物。   题解       动态规划      import java.util.ArrayList;import java.util.List;import java.util.Scanner;// P3public class Main {    public static void main(String[] args) {        Scanner in = new Scanner(System.in);        int n = in.nextInt(), H = in.nextInt(), A = in.nextInt();        Monster[] list = new Monster[n];        for (int i = 0; i < n; i++) list[i] = new Monster();        for (int i = 0; i < n; i++) list[i].h = in.nextInt();        for (int i = 0; i < n; i++) list[i].a = in.nextInt();        Solution solution = new Solution();        System.out.println(solution.solve(list, H, A));    }}class Monster {    public int h, a;    // 最多可以打败多个其他怪物    public int max;}class Solution {    public int solve(Monster[] list, int H, int A) {        List<Monster> monsters = new ArrayList<>();        for (Monster monster : list) {            if (monster.a < A && monster.h < H) {                monsters.add(monster);            }        }        Monster xm = new Monster();        xm.a = A;        xm.h = H;        monsters.add(xm);        monsters.sort((o1, o2) -> {            if (o1.a != o2.a) {                return o1.a - o2.a;            } else {                return o2.h - o1.h;            }        });        for (int i = 1; i < monsters.size(); i++) {            Monster cur = monsters.get(i);            for (int l = 0; l < i; l++) {                Monster prev = monsters.get(l);                if (prev.a < cur.a && prev.h < cur.h) {                    cur.max = Math.max(cur.max, prev.max + 1);                }            }        }        return xm.max;    }}   P4   小美有一个长度为n的数组,她想从中选出至少一个或多个数,使得这些个数的按位与的结果可以被  整除。例如小美有一个数组[1,2,4,12],那么她可以选出[4,12],因为 4 &12= 4,可以被  整除,所以 m 的最大值为 2。请帮小美选数,使得整数m尽可能的大。   输入描述   第一行一个整数几,表示数组的长度。   第二行几个整数 ,表示数组的元素。         输出描述   输出一个整数,表示 m 的最大值。   示例1   输入:51 2 3 20 28输出:2说明:选择20和28,20&28 = 20,可以被 22 整除,所以m 的最大值为 2。   题解       2^m == (1 << m) 从这里可以看出,如果 k % (2^m) == 0 这里的 m 就是k二进制后从低位到高位第一个1出现的位置。    然后两种情况进行枚举找到最佳答案:         只选中一个元素;     选择两个元素(元素没有相同的1位就没有必要进行选择,因为这样的选择不会优于只选择一个元素的情况);          import java.util.*;public class Main {    public static void main(String[] args) {        Scanner in = new Scanner(System.in);        int n = in.nextInt();        int[] a = new int[n];        for (int i = 0; i < n; i++) a[i] = in.nextInt();        Solution solution = new Solution();        System.out.println(solution.solve(a));    }}class Solution {    int max = 0;    public int solve(int[] a) {        // 对元素进行分组 groupMap.get(i) 表示二进制第i位值为1的数字        Map<Integer, List<Integer>> groupMap = new HashMap<>();        for (int num : a) {            int bit = 0;            boolean foundOne = false;            int k = num;            while (k != 0) {                if ((k & 1) == 1) {                    //这里更新结果,是判断只选当前元素是的结果值(即第一个1所在的位置)                    if (!foundOne) max = Math.max(bit, max);                    // Map<bit, num>                    groupMap.computeIfAbsent(bit, p -> new ArrayList<>()).add(num);                    foundOne = true;                }                k >>= 1;                bit++;            }        }        // 这里是尝试选取两个元素,进行求最佳的解        // 元素没有相同的1位就没有必要进行选择,因为这样的选择不会优于只选择一个元素的情况        for (List list : groupMap.values()) {            int n = list.size();            for (int i = 0; i < n; i++) {                int ai = (int) list.get(i);                for (int j = i + 1; j < n; j++) {                    int aj = (int) list.get(j);                    this.max = Math.max(max, f(ai & aj));                }            }        }        return max;    }    // 求 k 二进制,从低位到高位第一个1出现的位置,  这个位置即为 k % (2^m) == 0 的最大的 m    public int f(int k) {        int bit = 0;        while (k != 0) {            if ((k & 1) == 1) break;            k >>= 1;            bit++;        }        return bit;    }}   T5   地图上有n个城市,小                   
点赞 12
评论 2
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务