网易编程

来源:互联网 发布:金曲软件 编辑:程序博客网 时间:2024/06/05 04:56

题目描述

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

输入描述:

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

输出描述:

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

输入

37 4 72 50

输出

49

思路:DP,dp[i][j]表示以第i个学生结尾,选取j个人的最大值,注意可能有负数

package l1;import java.util.Scanner;/* * dp[i][j]表示以第i个学生结尾,选取j个人的最大值 *  * 还有负数 */public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();int[] a = new int[n];for(int i=0; i<n; i++)a[i]=sc.nextInt();int k = sc.nextInt(), d = sc.nextInt();long[][] dp = new long[1+n][k+1], dp2 = new long[1+n][1+k];dp[0][0] = 1;dp2[0][0] = 1;for(int i=1; i<=n; i++) {dp[i][0] = 1;dp2[i][0] = 1;for(int j=1; j<=Math.min(k, i); j++) {for(int p=i-1; i-p<=d && p>=j-1; p--) {if(a[i-1] >= 0) {dp[i][j] = Math.max(dp[i][j], dp[p][j-1]*a[i-1]);dp2[i][j] = Math.min(dp2[i][j], dp2[p][j-1]*a[i-1]);} else {dp[i][j] = Math.max(dp[i][j], dp2[p][j-1]*a[i-1]);dp2[i][j] = Math.min(dp2[i][j], dp[p][j-1]*a[i-1]);}}}}long max = Integer.MIN_VALUE;for(int i=1; i<=n; i++)max = Math.max(max, dp[i][k]);System.out.println(max);}}


题目描述

你就是一个画家!你现在想绘制一幅画,但是你现在没有足够颜色的颜料。为了让问题简单,我们用正整数表示不同颜色的颜料。你知道这幅画需要的n种颜色的颜料,你现在可以去商店购买一些颜料,但是商店不能保证能供应所有颜色的颜料,所以你需要自己混合一些颜料。混合两种不一样的颜色A和颜色B颜料可以产生(A XOR B)这种颜色的颜料(新产生的颜料也可以用作继续混合产生新的颜色,XOR表示异或操作)。本着勤俭节约的精神,你想购买更少的颜料就满足要求,所以兼职程序员的你需要编程来计算出最少需要购买几种颜色的颜料?

输入描述:

第一行为绘制这幅画需要的颜色种数n (1 ≤ n ≤ 50)第二行为n个数xi(1 ≤ xi ≤ 1,000,000,000),表示需要的各种颜料.

输出描述:

输出最少需要在商店购买的颜料颜色种数,注意可能购买的颜色不一定会使用在画中,只是为了产生新的颜色。
示例1

输入

31 7 3

输出

3
思路:最开始利用a^b^a=a,直接把结果保存在HashTable中,ME

public class ME {public static void main(String[] args) {Scanner sc = new Scanner(System.in);Set<Integer> alreadyHave = new HashSet<Integer>();int cnt = 0;int n = sc.nextInt();for(int i=0; i<n; i++) {int t = sc.nextInt();if(!alreadyHave.contains(t)) {Set<Integer> tmp = new HashSet<Integer>();for(int p : alreadyHave)tmp.add((p ^ t));alreadyHave.addAll(tmp);alreadyHave.add(t);cnt ++;}}System.out.println(cnt);}}

另外一种解法是:借鉴求矩阵的秩的过程,把线性运算改为异或运算就好了

/* * 通过线性变换求极大线性无关组,这里把“线性变换”改成了“异或变换” * 矩阵化为上下三角,求秩:高斯消元法:https://zh.wikipedia.org/wiki/%E9%AB%98%E6%96%AF%E6%B6%88%E5%8E%BB%E6%B3%95 * 区别在于线性变化是随便选取一行作为基准让别人消元,这里需要选取最大行,为什么? * 因为无论是线性变换还是异或变换,都是希望先尽量多的消掉高位 * 越大的数意味着高位上为1的越多,这样如果另外一个数高位上为1就可以异或消掉了(如果是0根本就不需要消掉) * 而,如果先选取小的数作为基准,一个更大的数也许就不能消掉高位了 */public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();int[] a = new int[n];for(int i=0; i<n; i++)a[i]=sc.nextInt();for(int i=n; i>0; i--) {Arrays.sort(a, 0, i);for(int j=i-2; j>=0; j--)if((a[i-1] ^ a[j]) < a[j]) a[j] = (a[i-1] ^ a[j]);// 也许没有把a[j]的最高位消除,但是这是最有可能的方案,别的更不可能}int zero = 0;while(zero<n && a[zero] == 0)zero++;System.out.println(n - zero);}}



题目描述

二货小易有一个W*H的网格盒子,网格的行编号为0~H-1,网格的列编号为0~W-1。每个格子至多可以放一块蛋糕,任意两块蛋糕的欧几里得距离不能等于2。
对于两个格子坐标(x1,y1),(x2,y2)的欧几里得距离为:
( (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) ) 的算术平方根
小易想知道最多可以放多少块蛋糕在网格盒子里。

输入描述:

每组数组包含网格长宽W,H,用空格分割.(1 ≤ W、H ≤ 1000)

输出描述:

输出一个最多可以放的蛋糕数
示例1

输入

3 2

输出

4
思路:找规律

package l5;import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt(), m = sc.nextInt();int ret = 0;if(n%4==0 || m%4==0) {ret = n*m/2;} else if(n%2==0 && m%2==0) {ret = (n/4*m/4*8) + (n/4*4+m/4*4) + 4;} else {ret = n*m/2 + 1; // 1是剩余的一行多出来的一个,比如奇数行是7,该列可以有4个}System.out.println(ret);}}