分巧克力 Java

题目描述
儿童节那天有 K位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。

小明一共有 N块巧克力,其中第 i 块是 Hi×Wi的方格组成的长方形。为了公平起见,小明需要从这 N块巧克力中切出 K块巧克力分给小朋友们。切出的巧克力需要满足:

形状是正方形,边长是整数
大小相同

例如一块 6×5的巧克力可以切出 6 块 2×2 的巧克力或者 2 块 3×3的巧克力。

当然小朋友们都希望得到的巧克力尽可能大,你能帮小明计算出最大的边长是多少么?
输入格式

第一行包含两个整数 N和 K以下 N行每行包含两个整数 Hi 和 Wi输入保证每位小朋友至少能获得一块 1×1的巧克力。
输出格式

输出切出的正方形巧克力最大可能的边长

数据范围

1≤N,K≤105

1≤Hi,Wi≤105

输入样例:

2 10
6 5
5 6

输出样例:

2

思路
这题总体还是二分
1.首先我们知道每块矩形巧克力对于给定的边长,最多能分成多少块正方形的巧克力,假设一块5*6的矩形巧克力,分成边长为2的正方形,5/2=2,6/2=3,所以最多能分成2*3=6块,然后我们稍加推导就能得出对于给定的正方形边长x,长为l,宽为w矩形,最多能分成(l/x)*(w/x)块。
2.其次我们要知道并不是所有的矩形巧克力都需要用,我就是这点踩了雷,没有认真读题,我一开始想的是正方形再大也不可能大于所有巧克力中边长最小的一个于是我就有了这样的代码`

	int r=100001;//r表示所有巧克力中最小的那条边,由于是二分法 ,它作为右边界
     for(int i=0;i<N;i++){
            ck[i][0]=input.nextInt();
            ck[i][1]=input.nextInt();
            if(r<Math.min(ck[i][0],ck[i][1]));
            r=Math.min(ck[i][0],ck[i][1]);
        }
`

人家只说了要求切出的正方形尽可能的大,没有说每一块巧克力都需要用到,留几块不用也是行的,也就是说我上面那串代码在无中生有,后来看了y总的视频才改过来,诶太菜太马虎了
3.由于我们采用的是二分法,且最少边长为1,所以边界就出来了l=1;r=100001,(r=所有矩形中最长的那条边也行,只不过需要判断,还不如直接写上题目所给的最大值)
4.有了边界,我们就需要看看边界内的整数是否符合条件,一直找到符合条件且边长最大的那个数,这个时候就需要一个check()函数来判断一下

public static int check(int ck[][],int mid,int N,int K){
        int m=0;
        for(int i=0;i<N;i++){
            m=m+(ck[i][0]/mid*ck[i][1]/mid);//求每块巧克力能分解的个数,并相加
            if(m>=K){ //如果大于目标个数就可以退出循环,1表示符合,0表示不符合
                return 1;
            }
        }
        return 0;
    }

然后就是全部代码:

import java.util.Scanner;

public class 分巧克力 {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        int N=input.nextInt();
        int K=input.nextInt();
        int l=1;
        int r=100001;
        int ck[][]=new int[N][2];
        //N块分给十个人
        for(int i=0;i<N;i++){
            ck[i][0]=input.nextInt();
            ck[i][1]=input.nextInt();
        }

        while (l<r){
            int mid=(l+r+1)/2; //这里需要加1是因为,假设最后循环到l=r-1,
           //只剩下两个数,mid=(l+r)/2的话,由于是向下取整
           //所以l=mid,如果此时check(mid)==1,符合条件的话,就会产生死循环

            if(check(ck,mid,N,K)==1){
                l=mid;
            }
            else
                r=mid-1;
        }
        System.out.println(l);
    }
    public static int check(int ck[][],int mid,int N,int K){
        int m=0;
        for(int i=0;i<N;i++){
            m=m+(ck[i][0]/mid*ck[i][1]/mid);
            if(m>=K){
                return 1;
            }
        }
        return 0;
    }

没了,能力有限很啰嗦,求大佬勿喷

猜你喜欢

转载自blog.csdn.net/qq_44844588/article/details/106896579