正题
题目链接:https://www.luogu.org/problem/U92904?contestId=23574
题目大意
用mmm根长度为1的火柴求能够圈住的最多块的地。
解题思路
显然如果刚好能够围成一个正方形那么一定是最优的,那么我们先将能够围成的围成一个最大的正方形,然后剩下的在边边围。
为什么是最优的?首先若最大围成一个k∗kk*kk∗k的正方形,剩下的材料一定不够在边上围出2∗k+12*k+12∗k+1个块,因为如果可以,就可以围出(k+1)∗(k+1)(k+1)*(k+1)(k+1)∗(k+1)的正方形,那如果不超过2∗k2*k2∗k个块,那剩下的在边上围就是最优的。
然后二分答案即可
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
ll T,n,ans;
int main()
{scanf("%lld",&T);while(T--){scanf("%lld",&n);ll l=0,r=1e9;ans=0;while(l<=r){ll mid=(l+r)/2;if(2*mid*mid+mid+mid<=n) l=mid+1;else r=mid-1;}ans+=r*r;n-=2*r*r+r+r;if(r&&n>=3){ans++,n-=3;ans+=min(n/2,r-1);n-=min(n/2,r-1)*2;}if(r&&n>=3){ans++,n-=3;ans+=min(n/2,r-1);n-=min(n/2,r-1)*2;}printf("%lld\n",ans);}
}