时间: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]);
}
}