春招备战2019/2/16——算法

本文探讨了两个算法问题:一是如何在包含正数、负数和0的数组中找到三个数的乘积,使乘积最大;二是如何计算两个大整数的乘积,不使用系统自带的大整数类型。文章提供了详细的解决方案,包括代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最大乘积

给定一个无序数组,包含正数、负数和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);
    	}
    }
        
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值