最大乘积
给定一个无序数组,包含正数、负数和0,要求从中找出3个数的乘积,使得乘积最大,要求时间复杂度:O(n),空间复杂度:O(1)
注:最大乘积只可能是 最大*(次大*第三大) 或者是 最大*(最小*次小)
大整数相乘
有两个用字符串表示的非常大的大整数,算出他们的乘积,也是用字符串表示。不能用系统自带的大整数类型。
注:new StringBuilder(num2).reverse(),对字符串进行反转
大整数相乘所得的长度小于等于这俩个字符串的长度和
d[i+j] += a*b; i,j为各自字符串的索引, a,b为字符串对应索引i,j的值
import java.util.Scanner;
public class Main {
public static void main(String []args) {
Scanner scanner = new Scanner(System.in);
String num1 = scanner.next();
String num2 = scanner.next();
System.out.println(multiply(num1, num2));
}
public static String multiply(String num1, String num2) {
num1 = new StringBuilder(num1).reverse().toString();
num2 = new StringBuilder(num2).reverse().toString();
int[] d = new int[num1.length()+num2.length()];
for(int i=0; i<num1.length(); i++) {
int a = num1.charAt(i) - '0';
for(int j=0; j<num2.length(); j++) {
int b = num2.charAt(j) - '0';
d[i+j] += a*b;
}
}
StringBuilder sb = new StringBuilder();
for(int i=0; i<d.length; i++) {
int digit = d[i] % 10;
int carry = d[i]/10;
sb.insert(0, digit);
if(i < d.length-1)
d[i+1] += carry;
}
while(sb.length() > 0 && sb.charAt(0) == '0') {
sb.deleteCharAt(0);
}
return sb.length() == 0 ? "0" : sb.toString();
}
}
六一儿童节
六一儿童节,老师带了很多好吃的巧克力到幼儿园。每块巧克力j的重量为w[j],对于每个小朋友i,当他分到的巧克力大小达到h[i] (即w[j]>=h[i]),他才会上去表演节目。老师的目标是将巧克力分发给孩子们,使得最多的小孩上台表演。可以保证每个w[i]> 0且不能将多块巧克力分给一个孩子或将一块分给多个孩子。
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(); //n个学生
int[] h = new int[n]; //学生
for(int i=0; i<h.length; i++) {
h[i] = sc.nextInt();
}
int m = sc.nextInt(); //m个巧克力
int[] w = new int[m]; //巧克力
for(int i=0; i<w.length; i++) {
w[i] = sc.nextInt();
}
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;
}else { //如果最小的巧克力比最小的学生要大
count++; //那就把这个糖果给他, count++
stuStart++; //给他之后, 把最小的学生加一个
if(stuStart == n) {
break; //如果最后一个学生都有糖了,就不找了
}
}
}
System.out.println(count);
}
}
迷宫寻路
假设一个探险家被困在了地底的迷宫之中,要从当前位置开始找到一条通往迷宫出口的路径。迷宫可以用一个二维矩阵组成,有的部分是墙,有的部分是路。迷宫之中有的路上还有门,每扇门都在迷宫的某个地方有与之匹配的钥匙,只有先拿到钥匙才能打开门。请设计一个算法,帮助探险家找到脱困的最短路径。如前所述,迷宫是通过一个二维矩阵表示的,每个元素的值的含义如下 0-墙,1-路,2-探险家的起始位置,3-迷宫的出口,大写字母-门,小写字母-对应大写字母所代表的门的钥匙
输入描述:
迷宫的地图,用二维矩阵表示。第一行是表示矩阵的行数和列数M和N
后面的M行是矩阵的数据,每一行对应与矩阵的一行(中间没有空格)。M和N都不超过100, 门不超过10扇。
输出描述:
路径的长度,是一个整数
注:
对于:& -- > 不管怎样,都会执行"&"符号左右两边的程序
对于:&& -- > 只有当符号"&&"左边程序为真(true)后,才会执行符号"&&"右边的程序。
<< : 左移运算符,num << 1,相当于num乘以2,num << 2,相当于num乘以2再乘以2
>> : 右移运算符,num >> 1,相当于num除以2,num >> 2,相当于num除以2再除以2
/**
* 假设一个探险家被困在了地底的迷宫之中,要从当前位置开始找到一条通往迷宫出口的路径。迷宫可以用一个二维矩阵组成,
* 有的部分是墙,有的部分是路。迷宫之中有的路上还有门,每扇门都在迷宫的某个地方有与之匹配的钥匙,只有先拿到钥匙才能打开门。请设计一个算法,帮助探险家找到脱困的最短路径。
* 如前所述,迷宫是通过一个二维矩阵表示的,每个元素的值的含义如下 0-墙,1-路,2-探险家的起始位置,3-迷宫的出口,大写字母-门,小写字母-对应大写字母所代表的门的钥匙
*/
package yycgutil;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
public static int[][] next = {{1,0}, {-1,0},{0, 1}, {0, -1}};
public static boolean[][][] flag;
static class Node {
int x;
int y;
int key;
int temp;
public Node(int x, int y, int key, int temp) {
this.x = x;
this.y = y;
this.key = key;
this.temp = temp;
}
}
public static void main(String []args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
sc.nextLine();
flag = new boolean[n][m][1025];
char[][] chars = new char[n][m];
for(int i=0; i<n; i++) {
chars[i] = sc.nextLine().toCharArray();
}
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
if(chars[i][j] == '2') {
System.out.println(BFSFind(i, j, n, m, chars));
return ;
}
}
}
}
private static int BFSFind(int i, int j, int n, int m, char[][] chars) {
Queue<Node> queue = new LinkedList<>();
queue.add(new Node(i, j, 0, 0));
while(!queue.isEmpty()) {
Node node = queue.poll();
for(int k=0; k<4; k++) {
int tempX = node.x + next[k][0];
int tempY = node.y + next[k][1];
int key = node.key;
int temp = node.temp + 1;
if(tempX<0 || tempX>=n || tempY<0 || tempY>=m || chars[tempX][tempY]=='0') {
continue;
}
if(chars[tempX][tempY] == '3')
return temp;
if(chars[tempX][tempY]<='z' && chars[tempX][tempY]>='a')
key = key|1<<(chars[tempX][tempY]-'a');
if(chars[tempX][tempY]<='Z' && chars[tempX][tempY]>='A' && (key & (1<<(chars[tempX][tempY]-'A')))==0)
continue;
if(!flag[tempX][tempY][key]) {
flag[tempX][tempY][key] = true;
queue.offer(new Node(tempX, tempY, key, temp));
}
}
}
return -1;
}
}
彩色的砖块
小易有一些彩色的砖块。每种颜色由一个大写字母表示。各个颜色砖块看起来都完全一样。现在有一个给定的字符串s,s中每个字符代表小易的某个砖块的颜色。小易想把他所有的砖块排成一行。如果最多存在一对不同颜色的相邻砖块,那么这行砖块就很漂亮的。请你帮助小易计算有多少种方式将他所有砖块排成漂亮的一行。(如果两种方式所对应的砖块颜色序列是相同的,那么认为这两种方式是一样的。)
例如: s = "ABAB",那么小易有六种排列的结果:
"AABB","ABAB","ABBA","BAAB","BABA","BBAA"
其中只有"AABB"和"BBAA"满足最多只有一对不同颜色的相邻砖块。
输入描述:
输入包括一个字符串s,字符串s的长度length(1 ≤ length ≤ 50),s中的每一个字符都为一个大写字母(A到Z)。
输出描述:
输出一个整数,表示小易可以有多少种方式。
/**
* 小易有一些彩色的砖块。每种颜色由一个大写字母表示。各个颜色砖块看起来都完全一样。
* 现在有一个给定的字符串s,s中每个字符代表小易的某个砖块的颜色。
* 小易想把他所有的砖块排成一行。如果最多存在一对不同颜色的相邻砖块,
* 那么这行砖块就很漂亮的。请你帮助小易计算有多少种方式将他所有砖块排成漂亮的一行。
* (如果两种方式所对应的砖块颜色序列是相同的,那么认为这两种方式是一样的。)
例如: s = "ABAB",那么小易有六种排列的结果:
"AABB","ABAB","ABBA","BAAB","BABA","BBAA"
其中只有"AABB"和"BBAA"满足最多只有一对不同颜色的相邻砖块。
*/
package yycgutil;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
public static void main(String []args) {
Scanner br = new Scanner(System.in);
String s = br.nextLine();
char a = ' ';
char b = ' ';
for(char ch : s.toCharArray()) {
if(a == ' ') {
a = ch;
}else if(ch != a && b == ' ') {
b = ch;
}else if(ch != a && ch != b) {
System.out.println(0);
return ;
}
}
if(a == ' ' && b == ' ') {
System.out.println(0);
}else if(a != ' ' && b == ' ') {
System.out.println(1);
}else {
System.out.println(2);
}
}
}