洛谷 P7892 题解

22 篇文章 0 订阅
22 篇文章 0 订阅

题目传送门

作为月赛的第一题,还是蛮简单的。

思路

首先,不要被样例所迷惑,样例给出的只是一种可行的方案,但并不是最优解,最优解应是围出一个 2 × 2 2\times2 2×2 的像素格,所需的栅栏数为 ( 2 + 1 ) × 2 + ( 2 + 1 ) × 2 = 12 (2+1)\times2+(2+1)\times2=12 (2+1)×2+(2+1)×2=12

接下来,因为题目中说明围成的像素格一定是一个长方形,所以可以根据长方形的周长与面积关系来做的,当这个长方形的面积一定时,构成这个长方形的不相邻的两条边差的绝对值越小,构成这个长方形的周长越小。

证明:
可以根据基本不等式 a + b > = 2 a b a+b>=2\sqrt{ab} a+b>=2ab 推出 ( a + b 2 ) 2 > = a b (\dfrac{a+b}{2})^2>=ab (2a+b)2>=ab,当且仅当 a = b a=b a=b 时等号成立。因为 a b ab ab 是已经确定的值了,所以当 a = b a=b a=b 时可以取到 a b ab ab 这一最小值,此时的 a + b a+b a+b 也一定是最小的即此时的周长也一定是是最小的,以此类推,也就推出了上面的结论。

知道了这些,剩下的也就比较简单了,可以先把输进来的面积 n n n 开方,然后找到离开方后的数最近的整数并且保证是 n n n 的因数即可求得最小的范围,最后求出周长即可。

具体看代码。

code

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int T;
long long l,n,m,ans;//保险
double f;//开方用
int main()
{
	scanf("%d",&T);
	while(T--){
		scanf("%lld%lld",&n,&m);
		f=sqrt(n);
		l=f;
		for(int i=l;i>=1;i--)//从最近的小于等于它的数往前找
			if(n%i==0){//可以构成长方形
				ans=(i+1)*2+(n/i+1)*2;
            			//i与n/i是构成面积为n的长方形的最短的两条不相邻的边
                    	//ans算最终结果
				break;//省时
			}
		if(ans>m)//判断
			cout<<"Miss"<<endl;
		else
			cout<<"Good"<<endl;
	}
	return 0;
}

完结撒花~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值