牛客网编程练习一

版权声明:from Hasson https://blog.csdn.net/has_son/article/details/86621059

最大乘积

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

}

猜你喜欢

转载自blog.csdn.net/has_son/article/details/86621059
今日推荐