[编程题]最大乘积
给定一个无序数组,包含正数、负数和0,要求从中找出3个数的乘积,使得乘积最大,要求时间复杂度:O(n),空间复杂度:O(1)
输入描述:
第一行是数组大小n,第二行是无序整数数组A[n]
输出描述:
满足条件的最大乘积
示例1
输入
4
3 4 1 2
输出
24
两种情况:三个最大正数;一个最大正数和两个最小负数
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int num=scanner.nextInt();
long []arr=new long[num];
for(int i=0;i<num;i++){
arr[i]=scanner.nextInt();
}
System.out.println(maxValue(arr));
}
public static long maxValue(long[] arr) {
long max = Integer.MIN_VALUE;
int zhengshu = 0;
int zero = 0;
int fushu = 0;
// 统计正数负数0的个数
for (int i = 0; i < arr.length; i++) {
if (arr[i] > 0) {
zhengshu++;
} else if (arr[i] == 0) {
zero++;
} else {
fushu++;
}
}
// 两周情况,三个正数,或者一个正数两个负数
long max1 = 0;
long max2 = 0, max3 = 0, min1 = 0, min2 = 0;
int index1 = -1, index2 = -1, index3 = -1;
// 首先如果能凑成三个正数
if (zhengshu >= 3) {
for (int i = 0; i < arr.length; i++) {
max1 = Math.max(max1, arr[i]);
if (max1 == arr[i]) {
index1 = i;
}
}
for (int i = 0; i < arr.length; i++) {
if (i != index1) {
max2 = Math.max(max2, arr[i]);
if (max2 == arr[i]) {
index2 = i;
}
}
}
for (int i = 0; i < arr.length; i++) {
if (i != index1 && i != index2) {
max3 = Math.max(max3, arr[i]);
if (max3 == arr[i]) {
index3 = i;
}
}
}
max = Math.max(max, max1 * max2 * max3);
}
// 一个正数两个负数
if (zhengshu >= 1 && fushu >= 2) {
// 正数
for (int i = 0; i < arr.length; i++) {
max1 = Math.max(max1, arr[i]);
if (max1 == arr[i]) {
index1 = i;
}
}
for (int i = 0; i < arr.length; i++) {
if (i != index1) {
min1 = Math.min(min1, arr[i]);
if (min1 == arr[i]) {
index1 = i;
}
}
}
for (int i = 0; i < arr.length; i++) {
if (i != index1 && i != index2) {
min2 = Math.min(min2, arr[i]);
}
}
max = Math.max(max, max1 * min1 * min2);
}
return max;
}
}
[编程题]小熊吃糖
有n只小熊,他们有着各不相同的战斗力。每次他们吃糖时,会按照战斗力来排,战斗力高的小熊拥有优先选择权。前面的小熊吃饱了,后面的小熊才能吃。每只小熊有一个饥饿值,每次进食的时候,小熊们会选择最大的能填饱自己当前饥饿值的那颗糖来吃,可能吃完没饱会重复上述过程,但不会选择吃撑。
现在给出n只小熊的战斗力和饥饿值,并且给出m颗糖能填饱的饥饿值。
求所有小熊进食完之后,每只小熊剩余的饥饿值。
输入描述:
第一行两个正整数n和m,分别表示小熊数量和糖的数量。(n <= 10, m <= 100)
第二行m个正整数,每个表示着颗糖能填充的饥饿值。
接下来的n行,每行2个正整数,分别代表每只小熊的战斗力和当前饥饿值。
题目中所有输入的数值小于等于100。
输出描述:
输出n行,每行一个整数,代表每只小熊剩余的饥饿值。
示例1
输入
2 5
5 6 10 20 30
4 34
3 35
输出
4
0
说明
第一只小熊吃了第5颗糖
第二只小熊吃了第4颗糖
第二只小熊吃了第3颗糖
第二只小熊吃了第1颗糖
import java.util.*;
class bear {
int power;
int hungry;
// 记住顺序,哎
int order;
public bear(int power, int hungry, int order) {
this.hungry = hungry;
this.power = power;
this.order = order;
}
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int bearsum = sc.nextInt();
int candysum = sc.nextInt();
bear[] bears = new bear[bearsum];
//int[] candyh = new int[candysum];
ArrayList<Integer> candyh=new ArrayList<Integer>();
for (int i = 0; i < candysum; i++) {
//candyh[i] = sc.nextInt();
candyh.add(sc.nextInt());
}
for (int i = 0; i < bearsum; i++) {
bears[i] = new bear(sc.nextInt(), sc.nextInt(), i);
}
// 累积吃的饥饿值
int[] full = new int[bearsum];
// 累积吃的数量
int[] candycount = new int[bearsum];
// 按照糖的大小排序
//Arrays.sort(candyh);
Collections.sort(candyh);
// 按照熊的力量排序
Arrays.sort(bears, new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
// TODO Auto-generated method stub
bear b1 = (bear) o1;
bear b2 = (bear) o2;
if (b1.power > b2.power) {
return 1;
}
if (b1.power < b2.power) {
return -1;
}
return 0;
}
});
for (int j = bearsum - 1; j >= 0; j--) {
for (int i = candyh.size()-1; i >= 0; i--) {
if(full[j]+candyh.get(i)<=bears[j].hungry){
full[j] = full[j] + candyh.get(i);
candyh.remove(i);
}
}
}
// 剩余的饥饿值
for (int i = 0; i < bearsum; i++) {
bears[i].hungry = bears[i].hungry - full[i];
}
// 按照order排序
Arrays.sort(bears, new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
// TODO Auto-generated method stub
bear b1 = (bear) o1;
bear b2 = (bear) o2;
if (b1.order > b2.order) {
return 1;
}
if (b1.order < b2.order) {
return -1;
}
return 0;
}
});
for (int i = 0; i < bearsum; i++) {
System.out.println(bears[i].hungry);
}
}
}
[编程题]数三角形
给出平面上的n个点,现在需要你求出,在这n个点里选3个点能构成一个三角形的方案有几种。
输入描述:
第一行包含一个正整数n,表示平面上有n个点(n <= 100)
第2行到第n + 1行,每行有两个整数,表示这个点的x坐标和y坐标。(所有坐标的绝对值小于等于100,且保证所有坐标不同)
输出描述:
输出一个数,表示能构成三角形的方案数。
示例1
输入
4
0 0
0 1
1 0
1 1
输出
4
说明
4个点中任意选择3个都能构成三角形
注意怎么判断三点共线,用斜率判断
import java.util.*;
class Point {
int x;
int y;
Point() {
}
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int sum = sc.nextInt();
Point[] points = new Point[sum];
for (int i = 0; i < sum; i++) {
points[i] = new Point(sc.nextInt(), sc.nextInt());
}
int count=0;
if(sum<3){
count=0;
}else{
for(int i=0;i<points.length-2;i++){
for(int j=i+1;j<points.length-1;j++){
for(int k=j+1;k<points.length;k++){
if(isTriangle(points[i], points[j], points[k])){
count++;
}
}
}
}
}
System.out.println(count);
}
// 判断三个点能不能构成三角形
public static boolean isTriangle(Point p1, Point p2, Point p3) {
boolean flag = false;
//三个点在一条直线上是false
if( (p1.x-p2.x)*(p1.y-p3.y) == (p1.y-p2.y)*(p1.x-p3.x)){
return flag;
}
double l1 = Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y-p2.y, 2));
double l2 = Math.sqrt(Math.pow(p2.x - p3.x, 2) + Math.pow(p2.y-p3.y, 2));
double l3 = Math.sqrt(Math.pow(p1.x - p3.x, 2) + Math.pow(p1.y-p3.y, 2));
if((l1-l2)<l3&&(l1+l2)>l3){
flag=true;
}
return flag;
}
}