HDU 6154 CaoHaha's staff(思维+找规律)

来源:互联网 发布:航天三院310所 知乎 编辑:程序博客网 时间:2024/06/02 02:12

题目大意:

输入一个数表示一个面积,然后输出最少画几划能够围成一个面积大于等于给定面积的多边形。

画线的规则是假设有一个正方形,你可以连它的一条边,或是对角线,一个正方形的面积是1。

分析:

因为数据范围在int内,所以应该是推出一个公式什么的直接套。

推公式:

我们从面积推边数好像不太现实,因为有的固定边围成的最大面积是非整数的,也就是面积到边数的映射不

是唯一的。但是,如果从边入手,当边数固定时,这些边所围成的最大的面积是固定的。我们发现,当边的数量

是4的倍数时,我们把它们围成一个菱形时面积最大,这样4就可以作为一个伪周期,为什么说是伪周期,因为每

个周期内的结果是不一样的,但是它们的规律是一样的。下面以图片的形式说明这个规律。


下面对于一个给出的面积k,先找到大于这个面积的4的整数倍那个边数,也就是图中的红色边,

即(i*sqrt(2))^2 >= k解出i>=sqrt(k/2)

这样再依次算出边减少3次的情况所对应的面积,找到面积大于k并且和k最接近的那个边数就是答案了。

代码:

#include <bits/stdc++.h>using namespace std;int main(){     int t,k;     scanf("%d",&t);     while(t--)     {         scanf("%d",&k);         int i=ceil(sqrt((double)k/2.0));         int bb[4];         bb[0]=4*i;         bb[1]=bb[0]-1;         bb[2]=bb[1]-1;         bb[3]=bb[2]-1;          /*  for(int i=0;i<4;i++)                cout<<bb[i]<<" ";            cout<<endl;*/         double aa[4];         aa[0]=2*i*i;         aa[1]=aa[0]-(double)(i*2+1)/2.0;         aa[2]=aa[1]-(double)((i-1)*2+1)/2.0;         aa[3]=aa[2]-(double)((i-1)*2+1)/2.0;         /*for(int i=0;i<4;i++)                cout<<aa[i]<<" ";            cout<<endl;*/         int biao=0;         for(int i=0;i<4;i++)         {             if(aa[i]>=k)                biao=i;         }        // cout<<"biao:"<<biao<<endl;         printf("%d\n",bb[biao]);     }    return 0;}