【2017中国大学生程序设计竞赛

【链接】点击打开链接


【题意】


给你一个面积,让你求围成这个面积最少需要几条边,其中边的连线只能是在坐标轴上边长为1的的线或者是两个边长为1 的线的对角线。

【题解】


找规律题

考虑s[i]表示i条边能组成的最大面积.

s[6]=4.

s[7]=4+1.5=5.5

s[8]=4+4=8

s[9]=8+1.5=9.5

s[10]=8+4=12

s[11]=12+2.5=14.5

s[12]=12+6=18

之后又重复一遍..s[13]=18+2.5,s[14]=18+6

可以发现,一开始x1 = 1.5,x2 = 4

之后每4次操作x2+=1,x2+=2;

然后这4次操作分别为s[i] = s[i-1]+x1,以及s[i] = s[i-2]+x2;

每次,都往长方形长边那个一个方向扩展一下且只用一条边

然后一开始的长方形变成正方形,然后正方形再扩展一下,变成长方形

然后又从长方形的长边。。。

所以x1,x2在长方形变成正方形又变成长方形的过程中才会重复有两次重复两次之后,x1,x2才扩展

之后找到最小的i;

使得所需面积<=s[i]就好.


【错的次数】


2

【反思】


直接按照所需面积去找答案并不好找。
应该从另外一面,也即i条边最大能围成的面积去思考。
从这个东西出发去寻找规律。
找规律的时候要认真啊。。。
不要太草率。

【代码】

#include <bits/stdc++.h>
using namespace std;
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define ri(x) scanf("%d",&x)
#define oi(x) printf("%d",x)

const int N = 1e5;
double s[N+10];

int main(){
    rep1(i,0,2) s[i] = 0;
    s[2] = 0.5;s[4] = 2,s[5] = 2.5,s[6] = 4;
    double x1 = 1.5,x2 = 4;
    rep1(i,7,N){
        int temp = (i - 7)%4;
        if (temp==0) s[i] = s[i-1] + x1;
        if (temp==1) s[i] = s[i-2] + x2;
        if (temp==2) s[i] = s[i-1] + x1;
        if (temp==3){
            s[i] = s[i-2] + x2;
            x1 += 1,x2 += 2;
        }
    }

    int T;
    ri(T);
    while (T--){
        int x,ans = 0;
        ri(x);
        rep1(i,0,N)
            if (x<=s[i]){
                ans = i;
                break;
            }
        oi(ans);puts("");
    }
    return 0;
}




原文地址:https://www.cnblogs.com/AWCXV/p/7626050.html