码迷,mamicode.com
首页 > 其他好文 > 详细

[蒟蒻梦想-CSP考前加油赛] B 画地为佬

时间:2019-11-13 00:27:58      阅读:85      评论:0      收藏:0      [点我收藏+]

标签:contest   inf   void   ref   tchar   else   n+1   head   ace   

画地为佬

没有想到什么好的算法……感觉很暴力的样子……

大致思路是先找一个刚刚好不越界的大正方形块,然后一根一根围墙往上加。

首先考虑方块数量与围墙之间的关系:

  1. 方块的数量是\(1^2\)
    围墙的数量是\(2 \times 1 \times(1+1)\)
0
  1. 方块的数量是\(2^2\)
    围墙的数量是\(2 \times 2 \times(1+2)\)
0 0
0 0
  1. 方块的数量为\(3^2\)
    围墙的数量是\(2 \times 3 \times(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} \rfloor \]

算除了大正方形还剩下多少围墙:
\[ rest=m-2n(n+1) \]

讨论剩下的围墙能围成几个块
\[ RestBlock=\left\{ \begin{aligned} & \lfloor (rest-1)/2 \rfloor ,\quad \quad rest \leq 2n+1\ & \lfloor (rest-1)/2 \rfloor +n, \ rest > 2n+1\\end{aligned} \right. \]

输出\(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('\n');
        }
        else
        {
            rest-=2*k+1;
            ll dlt= (rest-1)/2;
            pr(k*k+k+dlt);
            putchar('\n');
        }
        
    }
    return 0;
}

[蒟蒻梦想-CSP考前加油赛] B 画地为佬

标签:contest   inf   void   ref   tchar   else   n+1   head   ace   

原文地址:https://www.cnblogs.com/kion/p/11846230.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!