[编程题] 最大乘积
给定一个无序数组,包含正数、负数和0,要求从中找出3个数的乘积,使得乘积最大,要求时间复杂度:O(n),空间复杂度:O(1)输入描述:
无序整数数组A[n]
输出描述:
满足条件的最大乘积
输入例子1:
3 4 1 2
输出例子1:
24
最大乘积为最大的三个数字乘积或者最大一个数字和最小两个数字乘积,负负得正。
注意此题需要用long
第一种方法是排序,取得最值
第二种方法是使用五个变量
- import java.util.Arrays;
- import java.util.Scanner;
- public class Main {
- //nlgn用了排序
- public static void main1(String[] args) {
- Scanner sc = new Scanner(System.in);
- while (sc.hasNext()) {
- int n = sc.nextInt();
- long[] nums = new long[n];
- for (int i = 0; i < n; i++) {
- nums[i] = sc.nextLong();
- }
- Arrays.sort(nums);
- System.out.println(Math.max(nums[n - 1] * nums[0] * nums[1], nums[n - 1] * nums[n - 2] * nums[n - 3]));
- }
- }
- //O(n)
- public static void main(String[] args) {
- Scanner sc = new Scanner(System.in);
- while (sc.hasNext()) {
- int n = sc.nextInt();
- long[] nums = new long[n];
- for (int i = 0; i < n; i++) {
- nums[i] = sc.nextLong();
- }
- long max1 = Long.MIN_VALUE;
- long max2 = Long.MIN_VALUE;
- long max3 = Long.MIN_VALUE;
- long min1 = Long.MAX_VALUE;
- long min2 = Long.MAX_VALUE;
- for (int i = 0; i < n; i++) {
- if (nums[i] > max1) {
- max3 = max2;
- max2 = max1;
- max1 = nums[i];
- } else if (nums[i] > max2) {
- max3 = max2;
- max2 = nums[i];
- } else if (nums[i] > max3) {
- max3 = nums[i];
- }
- if (nums[i] < min1) {
- min2 = min1;
- min1 = nums[i];
- } else if (nums[i] < min2) {
- min2 = nums[i];
- }
- }
- System.out.println(Math.max(min1 * min2 * max1, max1 * max2 * max3));
- }
- }
- }
[编程题] 大整数相乘
有两个用字符串表示的非常大的大整数,算出他们的乘积,也是用字符串表示。不能用系统自带的大整数类型。输入描述:
空格分隔的两个字符串,代表输入的两个大整数
输出描述:
输入的乘积,用字符串表示
输入例子1:
72106547548473106236 982161082972751393
输出例子1:
70820244829634538040848656466105986748
- import java.util.*;
- public class Main {
- public static void main(String[] args) {
- Scanner sc = new Scanner(System.in);
- while (sc.hasNext()) {
- String str1 = sc.next();
- String str2 = sc.next();
- int alen = str1.length();
- int blen = str2.length();
- char[] s1 = str1.toCharArray();
- char[] s2 = str2.toCharArray();
- // 高低位对调
- covertdata(s1, alen);
- covertdata(s2, blen);
- // 两数乘积位数不会超过乘数位数和+ 3位
- int csize = alen + blen + 3;
- // 开辟乘积数组
- int[] c = new int[csize];
- // 乘积数组填充0
- for (int ii = 0; ii < csize; ii++) {
- c[ii] = 0;
- }
- // 对齐逐位相乘(没有进位处理)
- for (int j = 0; j < blen; j++) {
- for (int i = 0; i < alen; i++) {
- c[i + j] += Integer.parseInt(String.valueOf(s1[i])) * Integer.parseInt(String.valueOf(s2[j]));
- }
- }
- // System.out.println(Arrays.toString(c));
- int m = 0;
- // 进位处理
- for (m = 0; m < csize; m++) {
- int carry = c[m] / 10;
- c[m] = c[m] % 10;
- if (carry > 0)
- c[m + 1] += carry;
- }
- // 找到最高位(避免前导0)
- for (m = csize - 1; m >= 0;) {
- if (c[m] > 0)
- break;
- m--;
- }
- // 由最高位开始打印乘积
- for (int n = 0; n <= m; n++) {
- System.out.print(c[m - n]);
- }
- System.out.println("");
- }
- }
- public static void covertdata(char data[], int len) {
- // 高低位对调
- for (int i = 0; i < len / 2; i++) {
- data[i] += data[len - 1 - i];
- data[len - 1 - i] = (char) (data[i] - data[len - 1 - i]);
- data[i] = (char) (data[i] - data[len - 1 - i]);
- }
- }
- }
[编程题] 六一儿童节
六一儿童节,老师带了很多好吃的巧克力到幼儿园。每块巧克力j的重量为w[j],对于每个小朋友i,当他分到的巧克力大小达到h[i] (即w[j]>=h[i]),他才会上去表演节目。老师的目标是将巧克力分发给孩子们,使得最多的小孩上台表演。可以保证每个w[i]> 0且不能将多块巧克力分给一个孩子或将一块分给多个孩子。
输入描述:
第一行:n,表示h数组元素个数
第二行:n个h数组元素
第三行:m,表示w数组元素个数
第四行:m个w数组元素
输出描述:
上台表演学生人数
输入例子1:
3
2 2 3
2
3 1
输出例子1:
1
排序,贪心,计算总数
- import java.util.Arrays;
- import java.util.Scanner;
- public class Main {
- public static void main(String[] args) {
- Scanner sc = new Scanner(System.in);
- int n = sc.nextInt();
- int[] child = new int[n];
- for (int i = 0; i < n; i++) {
- child[i] = sc.nextInt();
- }
- int m = sc.nextInt();
- int[] cho = new int[m];
- for (int i = 0; i < m; i++) {
- cho[i] = sc.nextInt();
- }
- System.out.println(count(n,child,m,cho));
- }
- public static int count(int n,int[] child,int m ,int[] cho){
- int res = 0;
- Arrays.sort(child);
- Arrays.sort(cho);
- for (int i=0,j=0;i<m&j<n;i++){
- if (cho[i]>=child[j]){
- res++;
- j++;
- }
- }
- return res;
- }
- }
[编程题] 迷宫寻路
假设一个探险家被困在了地底的迷宫之中,要从当前位置开始找到一条通往迷宫出口的路径。迷宫可以用一个二维矩阵组成,有的部分是墙,有的部分是路。迷宫之中有的路上还有门,每扇门都在迷宫的某个地方有与之匹配的钥匙,只有先拿到钥匙才能打开门。请设计一个算法,帮助探险家找到脱困的最短路径。如前所述,迷宫是通过一个二维矩阵表示的,每个元素的值的含义如下 0-墙,1-路,2-探险家的起始位置,3-迷宫的出口,大写字母-门,小写字母-对应大写字母所代表的门的钥匙
输入描述:
迷宫的地图,用二维矩阵表示。第一行是表示矩阵的行数和列数M和N
后面的M行是矩阵的数据,每一行对应与矩阵的一行(中间没有空格)。M和N都不超过100, 门不超过10扇。
输出描述:
路径的长度,是一个整数
输入例子1:
5 5
02111
01a0A
01003
01001
01111
输出例子1:
7
这题就是普通的bfs多了‘钥匙’这个状态, 所以keys[x][y][key]的意义就是 横坐标为x,纵坐标为y,钥匙状态为key的点是否访问过, 钥匙的状态 就用二进制数表示 最多10 把钥匙 那就是1024, 比如我现在有第二把钥匙和第四把钥匙 那么我的钥匙状态就是 0101000000 也就是 320
- import java.util.LinkedList;
- import java.util.Scanner;
- public class Main {
- // 四个方向
- private static int[] xx = new int[] { 0, 0, 1, -1 };
- private static int[] yy = new int[] { 1, -1, 0, 0 };
- public static void main(String[] args) {
- Scanner scanner = new Scanner(System.in);
- while (scanner.hasNext()) {
- int m = scanner.nextInt();
- int n = scanner.nextInt();
- scanner.nextLine();
- char[][] datas = new char[m][n];
- for (int i = 0; i < m; i++) {
- datas[i] = scanner.nextLine().toCharArray();
- }
- int x0 = 0, y0 = 0;
- int xd = 0, yd = 0;
- for (int i = 0; i < m; i++) {
- for (int j = 0; j < m; j++) {
- if (datas[i][j] == '2') {
- x0 = i;
- y0 = j;
- continue;
- }
- if (datas[i][j] == '3') {
- xd = i;
- yd = j;
- break;
- }
- }
- }
- System.out.println(bfs(datas, m, n, x0, y0, xd, yd));
- }
- }
- private static int bfs(char[][] datas, int m, int n, int x0, int y0, int xd, int yd) {
- LinkedList<Node> queue = new LinkedList<>();
- int[][][] keys = new int[m][n][1024];
- for (int i = 0; i < m; i++) {
- for (int j = 0; j < n; j++) {
- for (int s = 0; s < 1024; s++) {
- keys[i][j][s] = Integer.MAX_VALUE;
- }
- }
- }
- queue.add(new Node(x0, y0, 0));
- keys[x0][y0][0] = 0;
- Node node = null;
- int x = 0;
- int y = 0;
- int key = 0;
- while (queue.size() > 0) {
- node = queue.poll();
- x = node.x;
- y = node.y;
- key = node.key;
- if (x == xd && y == yd)
- return keys[x][y][key];
- for (int i = 0; i < 4; i++) {
- x = node.x + xx[i];
- y = node.y + yy[i];
- key = node.key;
- if (!isValid(x, y, m, n, datas))
- continue;
- // 最多10把钥匙
- if (datas[x][y] >= 'a' && datas[x][y] <= 'j') {
- key = key | (0x1 << (datas[x][y] - 'a'));
- }
- // 有对应的钥匙继续往下走,没有则跳过
- if (datas[x][y] >= 'A' && datas[x][y] <= 'J') {// door
- if ((key & (0x1 << (datas[x][y] - 'A'))) > 0) {// haskey
- // key = key | ~(0x1 << (datas[x][y] - 'A'));
- } else {
- continue;
- }
- }
- // keys[x][y][key] 钥匙数
- if (keys[x][y][key] > keys[node.x][node.y][node.key] + 1) {
- keys[x][y][key] = keys[node.x][node.y][node.key] + 1;
- queue.add(new Node(x, y, key));
- }
- }
- }
- return Integer.MAX_VALUE;
- }
- private static boolean isValid(int x, int y, int m, int n, char[][] data) {
- if (x >= 0 && x < m && y >= 0 && y < n && data[x][y] != '0')
- return true;
- return false;
- }
- private static class Node {
- int x;
- int y;
- int key;
- public Node(int x, int y, int keys) {
- this.x = x;
- this.y = y;
- this.key = keys;
- }
- }
- }
此篇为转载。