[蒟蒻梦想-CSP考前加油赛] B 画地为佬
Posted kion
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[蒟蒻梦想-CSP考前加油赛] B 画地为佬相关的知识,希望对你有一定的参考价值。
没有想到什么好的算法……感觉很暴力的样子……
大致思路是先找一个刚刚好不越界的大正方形块,然后一根一根围墙往上加。
首先考虑方块数量与围墙之间的关系:
- 方块的数量是(1^2)
围墙的数量是(2 imes 1 imes(1+1))
0 |
---|
- 方块的数量是(2^2)
围墙的数量是(2 imes 2 imes(1+2))
0 | 0 |
---|---|
0 | 0 |
- 方块的数量为(3^2)
围墙的数量是(2 imes 3 imes(1+3))
0 | 0 | 0 |
---|---|---|
0 | 0 | 0 |
0 | 0 | 0 |
对于(n)块的情况,围墙的数量是(m=2n (1+n))
而现在给定的是围墙的数量(m),因此解方程(m=2n (1+n))。
由求根公式:
[ n=lfloor frac{ sqrt{4+8m}-2}{4} floor ]
算除了大正方形还剩下多少围墙:
[
rest=m-2n(n+1)
]
讨论剩下的围墙能围成几个块
[
RestBlock=left{
egin{aligned}
& lfloor (rest-1)/2
floor ,quad quad rest leq 2n+1 & lfloor (rest-1)/2
floor +n, rest > 2n+1\end{aligned}
ight.
]
输出(n^2+RestBlock).
代码的变量跟题目不一样,请留意。
code:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=105,INF=0x3f3f3f3f;
inline ll read()
{
char c=getchar();ll x=0;
for(;!isdigit(c);c=getchar());
for(;isdigit(c);c=getchar())
x=x*10+c-'0';
return x;
}
void pr(ll x)
{
if(x/10)pr(x/10);
putchar(x%10+'0');
}
int main()
{
//for(int i=1;i<100;i++)cout<<i<<' '<<((int)(sqrt(4+8*i)-2)/4)<<endl;
ll T=read();
while(T--)
{
ll n=read();
// cout<<T<<' ';
//ll n=T;
ll k= (sqrt(4+8*n)-2)/4;
ll rest=n-2*k*(k+1);
if(rest<=2*k+1)
{
ll dlt=(rest-1)/2;
pr(dlt+k*k);
putchar('
');
}
else
{
rest-=2*k+1;
ll dlt= (rest-1)/2;
pr(k*k+k+dlt);
putchar('
');
}
}
return 0;
}
以上是关于[蒟蒻梦想-CSP考前加油赛] B 画地为佬的主要内容,如果未能解决你的问题,请参考以下文章