笔试:编程题
0,1背包问题:
定义V(i,j):当前背包容量 j,前 i 个物品最佳组合对应的价值;
递推关系式:
1) j<w(i) V(i,j)=V(i-1,j)
2) j>=w(i) V(i,j)=max{ V(i-1,j),V(i-1,j-w(i))+v(i) }
参考:动态规划-01背包问题
网易2017春招笔试编程题集合:
两个CPU,多个任务;求最小时间;
输入:
5 3072 3072 7168 3072 1024
输出:
9216
解法:
动态规划问题;以总时长的一半作为容量,则对小于等于容量一半进行动态规划,sum减去动态规划的结果即为cpu中长的时间,即为结果;
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while(sc.hasNext()){ int n = sc.nextInt(); int[] val = new int[n + 1]; int sum = 0; for (int i = 1; i <= n; i++) { val[i] = sc.nextInt() / 1024; sum += val[i]; } int[][] rst = new int[n + 1][sum / 2 + 1]; for (int i = 1; i <= n; i++) { for (int j = 1; j <= sum/2; j++) { if (j < val[i]) rst[i][j] = rst[i - 1][j]; else rst[i][j] = Math.max(rst[i - 1][j], rst[i - 1][j - val[i]] + val[i]); } } System.out.println((sum - rst[n][sum / 2]) * 1024); } } }
赶去公司:
主要注意绝对值的处理;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int num = sc.nextInt(); int[] tX = new int[num]; int[] tY = new int[num]; for (int i = 0; i < num; i++) { tX[i] = sc.nextInt(); } for (int i = 0; i < num; i++) { tY[i] = sc.nextInt(); } int gx = sc.nextInt(); int gy = sc.nextInt(); int walkTime = sc.nextInt(); int taxiTime = sc.nextInt(); int rst = walkTime * (Math.abs(gx) + Math.abs(gy)); for (int i = 0; i < num; i++) { rst = Math.min(rst, walkTime * (Math.abs(tX[i]) + Math.abs(tY[i])) + taxiTime * (Math.abs(gx - tX[i]) + Math.abs(gy - tY[i]))); } System.out.println(rst); } }
调整队形:
B和G组成的字符串,调整为B和G分开,只能相邻调整,求最小次数;
解法:两种情况:B都在左边和B都在右边;遍历,计算每个字符移动到最左边需要的次数,比较两种情况最小值。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String str = sc.nextLine(); int bSum = 0; int gSum = 0; int bIndex = 0; int gIndex = 0; for (int i = 0; i < str.length(); i++) { if (str.charAt(i) == 'B') { bSum += i - bIndex++; } else gSum += i - gIndex++; } System.out.print(Math.min(bSum, gSum)); } }
消除重复元素:
重复元素,保留后出现的;
输入输出描述与示例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
输入描述: 输入包括两行: 第一行为序列长度n(1 ≤ n ≤ 50) 第二行为n个数sequence[i](1 ≤ sequence[i] ≤ 1000),以空格分隔 输出描述: 输出消除重复元素之后的序列,以空格分隔,行末无空格 输入例子1: 9 100 100 100 99 99 99 100 100 100 输出例子1: 99 100
解法:
首先数组读取数字,然后遍历数组使用HashSet保存所有结果;
再倒序遍历数组,判断set是否包含array[i],包含的话就list.add(0, arr[i]);最后遍历list输出str.trim();
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import java.util.ArrayList; import java.util.HashSet; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int len = sc.nextInt(); int[] array = new int[len]; for (int i = 0; i < len; i++) { array[i] = sc.nextInt(); } HashSet<Integer> set = new HashSet<>(); for (int i = 0; i < len; i++) { set.add(array[i]); } ArrayList<Integer> list = new ArrayList<>(); for (int i = len - 1; i >= 0; i--) { if (set.contains(array[i])) { list.add(0, array[i]); set.remove(array[i]); } } String str = ""; for (int i = 0; i < list.size(); i++) { str += list.get(i) + " "; } System.out.print(str.trim()); } }
魔力手环:
k次变换,每次变换为a[i] = a[i] + a[i + 1];其中a[n - 1] = a[n - 1] + a[0];
常规O(nk)解法,只能通过40%:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int k = sc.nextInt(); int[] array = new int[n]; for (int i = 0; i < n; i++) { array[i] = sc.nextInt(); } for (int cnt = 0; cnt < k; cnt++) { int tmp = array[0] % 100; for (int i = 0; i < n; i++) { if (i != n - 1) array[i] = array[i] + array[i + 1]; else array[i] = array[i] + tmp; if (array[i] > 100) array[i] = array[i] % 100; } } String str = ""; for (int i = 0; i < n; i++) { str += array[i] + " "; } System.out.print(str.trim()); } }
解法:快速幂;不太会;
工作安排: