2018校招真题【牛客网】练习(一)

1、最大乘积

题目描述:
给定一个无序数组,包含正数、负数和0,要求从中找出3个数的乘积,使得乘积最大,要求时间复杂度:O(n),空间复杂度:O(1)

思路:
找出最大三个和最小两个,返回最大三个乘积或最大和最小两个乘积。

注意点:
初值max0-max2赋值最小值,min0-min1赋值最大值。

代码:

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        long max_min[] = new long[5];
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        max_min[0] = Long.MIN_VALUE;
        max_min[1] = Long.MIN_VALUE;
        max_min[2] = Long.MIN_VALUE;
        max_min[3] = Long.MAX_VALUE;
        max_min[4] = Long.MAX_VALUE;
        for(int i=0;i<n;i++){
            long num = scanner.nextInt();
            if(num>max_min[0]){
                max_min[2] = max_min[1];
                max_min[1] = max_min[0];
                max_min[0] = num;
            }
            else if(num>max_min[1]){
                max_min[2] = max_min[1];
                max_min[1] = num;
            }
            else if(num>max_min[2]){
                max_min[2] = num;
            }
            if(num<max_min[4]){
                max_min[3] = max_min[4];
                max_min[4] = num;
            }
            else if(num<max_min[3]){
                max_min[3] = num;
            }
        }
        scanner.close();
        long result = Math.max(max_min[0]*max_min[3]*max_min[4],max_min[0]*max_min[1]*max_min[2]);
        System.out.println(result);
    }
}
2、大数相乘

题目描述:
有两个用字符串表示的非常大的大整数,算出他们的乘积,也是用字符串表示。不能用系统自带的大整数类型。

思路:
1、按位相乘得到结果
2、处理进位
3、去除多余的0

代码:

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(mul(num1,num2));
    }
    
    public static String mul(String num1,String num2){
        num1 = new StringBuffer(num1).reverse().toString();
        num2 = new StringBuffer(num2).reverse().toString();
        int[] result = new int[num1.length()+num2.length()];
        for(int i=0;i<num1.length();i++){
            int digit1 = num1.charAt(i)-'0';
            for(int j=0;j<num2.length();j++){
                int digit2 = num2.charAt(j)-'0';
                result[i+j]+=digit1*digit2;
            }
        }
        String str = "";
        for(int i=0;i<result.length;i++){
            while(result[i]>=10){
                result[i]-=10;
                if(i+1<result.length){
                    result[i+1]++;
                }
            }
            str = result[i] + str;
        }
        for(int i=0;i<str.length();i++){
            if(str.charAt(i)!='0'){
                str = str.substring(i);
                break;
            }
        }
        return str;
    }
}
3、六一儿童节

题目描述:
六一儿童节,老师带了很多好吃的巧克力到幼儿园。每块巧克力j的重量为w[j],对于每个小朋友i,当他分到的巧克力大小达到h[i] (即w[j]>=h[i]),他才会上去表演节目。老师的目标是将巧克力分发给孩子们,使得最多的小孩上台表演。可以保证每个w[i]> 0且不能将多块巧克力分给一个孩子或将一块分给多个孩子。

思路:
排序,将糖果w[j]逐个与小朋友h[i]逐个比较,如果满足则count++,小孩指针pointer++,j++;如果不满足则单纯j++,比较下一个

代码:

import java.util.Scanner;
import java.util.ArrayList;
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<m;i++){
            w[i] = scanner.nextInt();
        }
        scanner.close();
        sort(h);
        sort(w);
        int pointer = 0;
        int count = 0;
        for(int i=0;i<m&&pointer<n;i++){
            if(w[i]>=h[pointer]){
                count++;
                pointer++;
            }
        }
        System.out.println(count);
    }
    
    public static void sort(int[] a){
        for(int i=0;i<a.length-1;i++){
            for(int j=i+1;j<a.length;j++){
                if(a[i]>a[j]){
                    int temp = a[i];
                    a[i] = a[j];
                    a[j] = temp;
                }
            }
        }
    }
}
4、迷宫寻路

题目描述:
假设一个探险家被困在了地底的迷宫之中,要从当前位置开始找到一条通往迷宫出口的路径。迷宫可以用一个二维矩阵组成,有的部分是墙,有的部分是路。迷宫之中有的路上还有门,每扇门都在迷宫的某个地方有与之匹配的钥匙,只有先拿到钥匙才能打开门。请设计一个算法,帮助探险家找到脱困的最短路径。如前所述,迷宫是通过一个二维矩阵表示的,每个元素的值的含义如下 0-墙,1-路,2-探险家的起始位置,3-迷宫的出口,大写字母-门,小写字母-对应大写字母所代表的门的钥匙

思路:
考察的要点是图的广度优先遍历。起始点是“2”,如果遍历到“3”则返回;如果遍历到“0”则表示不通,跳过;如果遍历到“a-z”表明得到钥匙;如果遍历“A-Z”表明需要钥匙才能通过,否则不通,跳过。
关于钥匙,使用巧妙的1<<char-'a’来按位表示是否获得钥匙。

代码:

import java.util.*;

public class Main{
    static class Node{
        int x;
        int y;
        int key;
        int step;
        public Node(int x,int y,int key,int step){
            this.x = x;
            this.y = y;
            this.key = key;
            this.step = step;
        }
    }
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        int rows = scanner.nextInt();
        int cols = scanner.nextInt();
        char[][] matrix = new char[rows][cols];
        scanner.nextLine();
        for(int i=0;i<rows;i++){
            matrix[i] = scanner.nextLine().toCharArray();
        }
        scanner.close();
        for(int i=0;i<rows;i++){
            for(int j=0;j<cols;j++){
                if(matrix[i][j]=='2'){
                    System.out.println(bfs(i,j,matrix,rows,cols));
                    break;
                }
            }
        }
        
    }
    
    public static int bfs(int starti,int startj,char[][] matrix,int rows,int cols){
        Queue<Node> nodes = new LinkedList<>();
        boolean[][][] visit = new boolean[101][101][1025];
        int[][] move = new int[][]{{-1,0},{0,-1},{1,0},{0,1}};
        nodes.offer(new Node(starti,startj,0,0));
        while(!nodes.isEmpty()){
            Node node = nodes.poll();
            for(int i=0;i<4;i++){
                int nextx = node.x+move[i][0];
                int nexty = node.y+move[i][1];
                int key = node.key;
                if(nextx<0||nextx>=rows||nexty<0||nexty>=cols||matrix[nextx][nexty]=='0'){
                    // unreachable
                    continue;
                }else if(matrix[nextx][nexty]=='3'){
                    // achieve goal
                    return node.step+1;
                }else if(matrix[nextx][nexty]<='z'&&matrix[nextx][nexty]>='a'){
                    // add key
                    key = (key|1<<(matrix[nextx][nexty]-'a'));
                }else if(matrix[nextx][nexty]<='Z'&&matrix[nextx][nexty]>='A'
                        &&(key&(1<<(matrix[nextx][nexty]-'A')))==0){
                    // no key unreachable
                    continue;
                }
                if(!visit[nextx][nexty][key]){
                    visit[nextx][nexty][key] = true;
                    nodes.offer(new Node(nextx,nexty,key,node.step+1));
                }
            }
        }
        return -1;
    }
}
5、彩色的砖块

题目描述:
小易有一些彩色的砖块。每种颜色由一个大写字母表示。各个颜色砖块看起来都完全一样。现在有一个给定的字符串s,s中每个字符代表小易的某个砖块的颜色。小易想把他所有的砖块排成一行。如果最多存在一对不同颜色的相邻砖块,那么这行砖块就很漂亮的。请你帮助小易计算有多少种方式将他所有砖块排成漂亮的一行。(如果两种方式所对应的砖块颜色序列是相同的,那么认为这两种方式是一样的。)
例如: s = “ABAB”,那么小易有六种排列的结果:
“AABB”,“ABAB”,“ABBA”,“BAAB”,“BABA”,“BBAA”
其中只有"AABB"和"BBAA"满足最多只有一对不同颜色的相邻砖块。

思路:
一种字母只有一种,两种字母有两种,其他则为零种。故题目即判断字符串里有多少个不同的字母。

代码:

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();
        scanner.close();
        HashSet<Character> chars = new HashSet<>();
        for(int i=0;i<input.length();i++){
            chars.add(input.charAt(i));
        }
        switch(chars.size()){
            case 1: System.out.println(1);break;
            case 2: System.out.println(2);break;
            default: System.out.println(0);break;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值