8.8 网易笔试

分析

时间:1个小时40分钟
四道题,难度还可以,太菜只写出了第一道第三道

1、
牛牛现在有一个包含N的正整数的数组a,牛牛可以将其中的每个数a[i] 都拆成若干个和为 a[i] 的整数,牛牛想知道这个数组最多能有多少素数?

输入描述
	第一行一个正整数n表示数组的长度
	第二行n个正整数表示a[i]的值
	1 <= n <= 1e6,1 <= a[i] <= 1e9
输出描述
	拆后数组最多的素数个数
示例1
输入
3
1 1 1
输出
0
说明
由于1不能再拆,并且1不是素数,所以拆后最多有0个素数
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        long ans = 0;
        int n = sc.nextInt();
        for(int i = 0; i < n; i++)
        	ans += sc.nextInt() >> 1;
        System.out.print(ans);
    }
}

2、
有三种难度的题目分别为Easy/Medium/Hard,现在你总共有E+EM+M+MH+H道题,各个字符串的含义如下:

E表示有E道题目难度为Easy
EM表示有EM道题目难度为Easy或者Medium
M表示有M道题目难度为Medium
MH表示有MH道题目难度为Medium或者Hard
H表示有H道题目难度为Hard

你要用这些题目出尽量多的模拟赛,为了保证题目质量且含有一定的区分量,每场模拟赛需要包含Easy Medium Hard三种难度的题目各一道,求你最多能出多少场模拟赛

分析:

  • 二分查找,不断探索符合条件的最大 target 值。

  • 先对 e,h 进行分析,是否满足 target 个方案,不够的话, e 用 em 补充,h 用 mh 补充

  • 最后判断 e,h, 和 m +em + mh 三个级别的个数是否满足条件,
    即 e >= target && h >= target && m + em + mh >= target
    如果满足条件,增大target 值,继续探索。

  • 此处用二分查找来缩小每一步探索的范围,满足的话 left = mid +1

  • 不满足的话,right = mid -1

public class Main {
    private  static int score;
    private static int max;
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int n = Integer.parseInt(sc.nextLine());
        String[] arr = sc.nextLine().trim().split(" ");
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = Integer.parseInt(arr[i]);
        }
        max = 0;
        int res = EMH(nums);
        System.out.println(res);
    }

    private static int EMH(int[] nums) {

        int e = nums[0];
        int m = nums[2];
        int h = nums[4];
        int em = nums[1];
        int mh = nums[3];

        int maxval = (e + m + h + em + mh) /3;
        int left = 0,right = maxval + 1;
        while (left <= right){

            int mid = (left + right)/2;
            if(binarySearch(mid,e,m,h,em,mh)){
                //若满足
                left = mid + 1;
                max = Math.max(max,mid);
            }
            else {
                right = mid-1;
            }
        }
        return max;
    }
    {
	private static boolean binarySearch(int mid, int e, int m, int h, int em, int mh) {
        //1.先处理 e, e 与要求的 mid 相比,少几个就从 em 中拿几个,假设 em是充足的
        if(mid > e){
            int cur = Math.min(mid - e,em);
            e += cur;
            em -= cur;
        }
        //2 处理 h ,h 与要求的 mid 相比,少几个就从 mh 中拿几个,假设 mh 是充足的
        if(mid > h){
            int cur = Math.max(mid - h ,mh);
            h += cur;
            mh -= cur;
        }
        // 3 判断拿完之后是否符合条件
        return e >= mid && h >= mid && (m + em + mh) >= mid;

    }
   }

3、
给了 n 个物品和它对应的价值。可以舍弃一部分物品,要两个人平分这些物品(数量可以不一样,价值总和要一样),
问最少舍弃多少价值。n < 15

分析: 回溯法,每趟共三种情况,给 人物 A, 给人物B, 抛弃终止条件是 A B 价值相同。

public class LeastGiveUp {
    private static int min = Integer.MAX_VALUE;
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int t = Integer.parseInt(sc.nextLine());
        while(t > 0 ){
            t--;
            int n = Integer.parseInt(sc.nextLine());
            String[] arr = sc.nextLine().trim().split(" ");
            int[] nums = new int[n];
            for (int i = 0; i < n; i++) {
                nums[i] = Integer.parseInt(arr[i]);
            }
            LessGiveUp(nums,n);
            System.out.println(min);
            min = Integer.MIN_VALUE;
        }
    }

    private static void LessGiveUp(int[] nums,int n) {
        int[] visited = new int[n];
        dfs(nums,0,0,0,0);

    }

    private static void dfs(int[] nums, int index, int A, int B, int giveup) {
        if(index == nums.length) {
            if (A == B && giveup < min) {
                min = giveup;
            }
                return;
        }
        dfs(nums,index+1,A + nums[index],B,giveup);
        dfs(nums,index +1,A,B + nums[index],giveup);
        dfs(nums,index+1,A,B,giveup+nums[index]);

    }
}

你可能感兴趣的:(笔试编程题)