最大乘积
题目描述
给定一个无序数组,包含正数、负数和0,要求从中找出3个数的乘积,使得乘积最大,要求时间复杂度:O(n),空间复杂度:O(1)
输入描述:
无序整数数组A[n]
输出描述:
满足条件的最大乘积
示例1
输入
3 4 1 2
输出
24
解决思路
考虑到数据可能是负数,所以乘积最大的三个数可能为最大*第二大*第三大 或者 最大*最小*第二小
所以直接遍历即可
代码
#include <iostream>
#include <vector>
using namespace std;
int main()
{
long n;
cin>>n;
vector<long> vec(n);
long a;
long fmax=0,smax=0,tmax=0;
long fmin=0,smin=0;
while(n--){
cin>>vec[n];
if(vec[n] > fmax)
{
tmax = smax;
smax = fmax;
fmax = vec[n];
}
else if(vec[n] > smax)
{
tmax = smax;
smax = vec[n];
}
else if (vec[n] > tmax)
{
tmax = vec[n];
}
else if(vec[n] < fmin)
{
smin = fmin;
fmin = vec[n];
}
else if (vec[n] < smin)
{
smin = vec[n];
}
}
long mul = fmax*smax*tmax > fmax*smin*fmin?fmax*smax*tmax:fmax*smin*fmin;
cout<<mul<<endl;
}
大整数相乘
题目描述
有两个用字符串表示的非常大的大整数,算出他们的乘积,也是用字符串表示。不能用系统自带的大整数类型。
输入描述:
空格分隔的两个字符串,代表输入的两个大整数
输出描述:
输入的乘积,用字符串表示
示例1
输入
72106547548473106236 982161082972751393
输出
70820244829634538040848656466105986748
解决思路
把大数存到字符串中,对每一位都进行乘法(不进行进位处理)
最后统一进行进位处理,注意字符和整形之间的变化。
代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String a = scanner.next();
String b = scanner.next();
System.out.println(mul(a, b));
}
// 逐个相乘
public static String mul(String a, String b) {
a = new StringBuilder(a).reverse().toString();
b = new StringBuilder(b).reverse().toString();
int[] d = new int[a.length() + b.length()];
for (int i = 0; i < a.length(); i++) {
int aIndex = a.charAt(i) - '0';
for (int j = 0; j < b.length(); j++) {
int bIndex = b.charAt(j) - '0';
d[i + j] += aIndex * bIndex;
}
}
// 处理进位
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < d.length; i++) {
int digit = d[i] % 10;
int carry = d[i] / 10;
sBuilder.insert(0, digit);
if (i < d.length - 1)
d[i + 1] += carry;
}
while (sBuilder.length() > 0 && sBuilder.charAt(0) == '0') {
sBuilder.deleteCharAt(0);
}
return sBuilder.length() == 0 ? "0" : sBuilder.toString();
}
}
六级儿童节
题目描述
六一儿童节,老师带了很多好吃的巧克力到幼儿园。每块巧克力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
解题思路
贪心算法,把最小的糖先给需要糖最小的孩子,如果小于之,则给第二小的孩子。大于之则给他,并进行第二小的糖比较。
代码
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] h = new int[n];
for (int i = 0; i < n; i++) {
h[i] = scanner.nextInt();
}
int m = scanner.nextInt();
int[] w = new int[m];
for (int i = 0; i < w.length; i++) {
w[i] = scanner.nextInt();
}
System.out.println(sixOne(m, n, h, w));
}
public static int sixOne(int m, int n, int h[], int w[]) {
Arrays.sort(w);// 巧克力排序
Arrays.sort(h);// 学生排序
int stuStart = 0;
int count = 0;
for (int i = 0; i < w.length; i++) {
if (w[i] > h[stuStart]) {
continue;
}
count++;
stuStart++;
if (stuStart == n) {
break;
}
}
return count;
}
}
迷宫寻路
题目描述
假设一个探险家被困在了地底的迷宫之中,要从当前位置开始找到一条通往迷宫出口的路径。迷宫可以用一个二维矩阵组成,有的部分是墙,有的部分是路。迷宫之中有的路上还有门,每扇门都在迷宫的某个地方有与之匹配的钥匙,只有先拿到钥匙才能打开门。请设计一个算法,帮助探险家找到脱困的最短路径。如前所述,迷宫是通过一个二维矩阵表示的,每个元素的值的含义如下 0-墙,1-路,2-探险家的起始位置,3-迷宫的出口,大写字母-门,小写字母-对应大写字母所代表的门的钥匙
输入描述:
迷宫的地图,用二维矩阵表示。第一行是表示矩阵的行数和列数M和N
后面的M行是矩阵的数据,每一行对应与矩阵的一行(中间没有空格)。M和N都不超过100, 门不超过10扇。
输出描述:
路径的长度,是一个整数
示例1
输入
5 5
02111
01a0A
01003
01001
01111
输出
7
解题思路
首先定义一个类,含到达这个点时的坐标,钥匙状态,以及步数。
因为一共有十把钥匙,要么有要么没有,所以钥匙可以用二进制表示。
所以从2点开始深度探索。捡到钥匙或遇到门都进行异或运算。直到遇到3(出口)
注意不要越界
代码
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
static class Node {
int x, y, k, step;
public Node(int x, int y, int k, int step) {
this.x = x;
this.y = y;
this.k = k;
this.step = step;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
int M = scanner.nextInt();
scanner.nextLine();
char[][] G = new char[N][M];
for (int i = 0; i < N; i++) {
G[i] = scanner.nextLine().toCharArray();
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (G[i][j] == '2') {
System.out.println(bfs(i, j, N, M, G));
}
}
}
}
private static int bfs(int i, int j, int N, int M, char[][] G) {
Queue<Node> queue = new LinkedList<>();
int[][][] mp = new int[101][101][1025];
int[][] next = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } };
int x, y;
queue.offer(new Node(i, j, 0, 0));
while (!queue.isEmpty()) {
Node node = queue.poll();
for (int q = 0; q < 4; q++) {
x = node.x + next[q][0];
y = node.y + next[q][1];
int key = node.k;
if (x < 0 || x >= N || y < 0 || y >= M || G[x][y] == '0')
continue;
else if (G[x][y] == '3')
return node.step + 1;
else if (G[x][y] <= 'z' && G[x][y] >= 'a')
key = key | (1 << (G[x][y] - 'a'));
else if (G[x][y] <= 'Z' && G[x][y] >= 'A' && (key & (1 << (G[x][y] - 'A'))) == 0)
continue;
if (mp[x][y][key] == 0) {
mp[x][y][key] = 1;
queue.offer(new Node(x, y, key, node.step + 1));
}
}
}
return 0;
}
}