首页 > 编程语言 >蓝桥杯2017年第八届真题-分巧克力(二分算法)

蓝桥杯2017年第八届真题-分巧克力(二分算法)

时间:2024-03-24 13:03:36浏览次数:28  
标签:巧克力 真题 int mid long check 蓝桥 2017 小朋友

题目描述

儿童节那天有K位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。
小明一共有N块巧克力,其中第i块是Hi x Wi的方格组成的长方形。


为了公平起见,小明需要从这 N 块巧克力中切出K块巧克力分给小朋友们。切出的巧克力需要满足:


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


例如一块6x5的巧克力可以切出6块2x2的巧克力或者2块3x3的巧克力。


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

输入格式

第一行包含两个整数N和K。(1 <= N, K <= 100000)
以下N行每行包含两个整数Hi和Wi。(1 <= Hi, Wi <= 100000)
输入保证每位小朋友至少能获得一块1x1的巧克力。

输出格式

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

样例输入

复制

2 10
6 5
5 6

样例输出

复制

2

个人分析

这个博客是我自己用来记录二分算法的模板的 如果我记录的有错误 烦请谅解

这是一个二分的模板

while (l < r)
	{
		mid = (l + r + 1) / 2;//(如果r=mid-1 那么就需要将mid+1)
		if (check(mid) == true)//检查中点是否符合要求
		{
			l = mid;
		}
		else
		{
			r = mid - 1;
		}
	}
其中一般mid=(l + r)/2

但是因为存在了r = mid-1 那么就需要在(l+r)里面再加上1 否则会出现死循环

首先if (check(mid) == true)是检查中点处是否符合规则

check检查的规则是看巧克力分的总数sum有没有大于小孩子的数量k

如果检查符合规则 那么就是在中点左边的边长一定可以分出足够多的巧克力给小朋友

但是我需要找的是尽可能最大的巧克力 所以需要往右边找 也就是缩左边界l=mid

(这里不让mid+1是因为中点mid是符合规则的 不能把mid给舍弃)

如果程序到达else条件下 说明中点检查不符合规则

那么就需要往左边找 要缩右边界 也就是r=mid-1

(这里要让mid-1是因为mid本身是不符合规则的 所以需要舍弃)

题解代码

//#include<bits/stdc++.h> //vs2022不让用 交题目的时候可以用
#include<iostream>
using namespace std;
long long int n, k;
long long int food[100001][2] = { {0} };
long long int l, r;

bool check(long long int e)
{
	long long int sum = 0;
	for (long long int i = 1; i <= n; i++)
	{
		sum = sum + (food[i][0] / e) * (food[i][1] / e);
	}
	if (sum < k)//分的总数量小于小孩子的数量
	{
		return false;
	}
	return true;
}
int main()
{
	scanf("%lld %lld", &n, &k);
	for (long long int i = 1; i <= n; i++)
	{
		scanf("%lld %lld", &food[i][0], &food[i][1]);
	}
	l = 1, r = 100000;
	long long int mid;
	while (l < r)
	{
		mid = (l + r + 1) / 2;//(如果r=mid-1 那么就需要将mid+1)
		if (check(mid) == true)//检查中点是否符合要求
		{
			l = mid;
		}
		else
		{
			r = mid - 1;
		}
	}
	printf("%lld\n",l);
	return 0;
}

标签:巧克力,真题,int,mid,long,check,蓝桥,2017,小朋友
From: https://blog.csdn.net/m0_74242327/article/details/136985717

相关文章

  • 蓝桥杯—蓝肽子序列—动态规划
    蓝肽子序列dp[i][j]表示L1,L2前i,j个字段有多少个公共子序列,对于一个Xi和Yj(L1,L2的前i,j个字段形成序列.如果xi=yj(第i,j字段),则dp[i][j]=dp[i-1][j-1]+1(前面的公共字段加一).否则,dp[i][j]=max(dp[i-1][j],dp[i][j-1]),考虑前后情况的最大值。最后输......
  • [暴力题解系列] 2023年蓝桥杯-冶炼金属
    世界上存在很难的题,但不存在暴力偷不到分的题​ 这题的暴力思路比你想的更简单,我直接枚举v的数值不就行了?#include<iostream>#include<algorithm>usingnamespacestd;inta[10010],b[10010];intmain(){intn;scanf("%d",&n);for(inti=1;i<=n;i++)......
  • 【华为OD机试】真题A卷-连接器问题(C++)
    一、题目描述【华为OD机试】真题A卷-连接器问题(C++)题目描述:有一组区间[a0,b0],[a1,b1],…(a,b表示起点,终点),区间有可能重叠、相邻,重叠或相邻则可以合并为更大的区间;给定一组连接器[x1,x2,x3,…](x表示连接器的最大可连接长度,即x>=gap),可用于将分离的区间连接起来,但两个分离区间之间只......
  • 【华为OD机试】真题A卷-垃圾短信识别(JAVA)
    一、题目描述【华为OD机试】真题A卷-垃圾短信识别(JAVA)题目描述:大众对垃圾短信深恶痛绝,希望能对垃圾短信发送者进行识别,为此,很多软件增加了垃圾短信的识别机制。经分析,发现正常用户的短信通常具备交互性,而垃圾短信往往都是大量单向的短信,按照如下规则进行垃圾短信识别: 本......
  • 【华为OD机试】真题A卷-快速开租建站(Python)
    一、题目描述【华为OD机试】真题A卷-快速开租建站(Python)题目描述:当前IT部门支撑了子公司颗粒化业务,该部门需要实现为子公司快速开租建站的能力,建站是指在一个全新的环境部署一套IT服务。1:每个站点开站会由一系列部署任务项构成,每个任务项部署完成时间都是固定和相等的,设为1......
  • 【华为OD机试】真题A卷-快递业务站(JAVA)
    一、题目描述【华为OD机试】真题A卷-快递业务站(JAVA)题目描述:快递业务范围有N个站点,A站点与B站点可以中转快递,则认为A-B站可达,如果A-B可达,B-C可达,则A-C可达。现在给N个站点编号0、1、…n-1,用s[i][j]表示i-j是否可达,s[i][j]=1表示i-j可达,s[i][j]=0......
  • 【蓝桥杯·dp问题】砝码称重
    此题易联想到使用动态规划解决,dp[i][j]状态表示是否存在前i个砝码中选取重量为j的方案。砝码重量分三种情况:1.砝码本身的重量(即一个砝码就可以表示的重量)2.放在同侧3.放在异侧注意重量为0的情况不记作方案数。#include<cstdio>#include<cstring>#include<iostream......
  • [暴力题解系列]2023年蓝桥杯-子串简写
    ​ 大伙都说暴力是最低级的算法,啊那确实。但是好的暴力才是真正牛逼的骗分。咱就是说,暴力如何骗分呢?就是基于最暴力的算法一步步优化到能得更多分的暴力。子串简写这题,首先第一步就能想到一件事情:暴力枚举子串开头和末尾的位置,检查是否是符合题目要求的字符,如果是,并且长度大于......
  • 中国电子学会(CEIT)2021年03月真题C语言软件编程等级考试三级(含详细解析答案)
    中国电子学会(CEIT)考评中心历届真题(含解析答案)C语言软件编程等级考试三级2021年03月编程题五道 总分:100分一、找和为K的两个元素(20分)在一个长度为n(n<1000)的整数序列中,判断是否存在某两个元素之和为k。时间限制:1000ms内存限制:65536kb输入第一行输入......
  • 【蓝桥杯】(3.19矩形总面积)
    #include<iostream>#defineLLlonglongusingnamespacestd;intmain(){LLx1,y1,x2,y2,x3,y3,x4,y4;cin>>x1>>y1>>x2>>y2>>x3>>y3>>x4>>y4;LLs1,s2,s;s1=(x2-x1)*(y2-y1);s2=(x4-......