题目传送门
作为月赛的第一题,还是蛮简单的。
思路
首先,不要被样例所迷惑,样例给出的只是一种可行的方案,但并不是最优解,最优解应是围出一个 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;
}
完结撒花~~