HDU5047 - Sawtooth[找规律]

本文探讨了一种通过放置特定形状(M型锯齿)来将无限矩形区域划分成尽可能多个子区域的方法。通过分析锯齿与先前放置的锯齿之间的交点规律,推导出一种数学公式来计算最多可划分的区域数量。该解决方案适用于大规模问题,例如当锯齿的数量达到10^12时。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ProblemSawtooth
Description :

一个无限大的矩形区域,现在 N 个“M”型的折线,可以看下题中的图,两边两条线是平行的(其实不平行也是没关系的,答案都是一样),问最多能把这个矩形分成多少个区域。

Solution

就是找规律,首先,我们会想到另一种最简单的情况,就是N条直线能把这个区域分成多少个区域,我们会看这条线与前面 N1 条线有多少个交点;那么这个题我们也是一样的,把当前这个“M”拆成4条射线,然后每条射线来与前面的 4(N1) 条射线求交点,这里要贪心最大化,就是说,每条射线在题目要求的范围内要穿过所有射线并出头一点,这样可以发现,前3条射线中每条射线使得区域数在前 4(N1) 条射线所形成的最大区域数上增加 4(N1) 个,而最后一条射线会比之前的每一条射线多出1个区域也就是 4(N1)+1 ,这是因为最后一条射线会比之前3条射线多交一条射线.

ansn=ansn1+44(n1)+1=ansn1+16n15=ansn2+16(n+n1)152=ans1+16(2+3++n)15(n1)=2+(8n+1)(n1)

这里 n 可达1012,所以还需要用大整数搞一下.

Code

#include <stdio.h>
#include <string.h>

typedef long long LL;

#define MAX_LINE 64

int toString(LL n, int a[])
{
    int top = 0;
    for (; n ; n /= 10)
        a[top++] = n % 10;
    if (!top)
        a[top++] = 0;
    return top;
}

// ans = (8 * n + 1) * (n - 1) + 2

int main()
{
    int T, K = 1;
    for (scanf("%d", &T); T-- ; K++) {
        LL n;
        scanf("%I64d", &n);
        LL tmp1 = 8LL * n + 1, tmp2 = n - 1;

        int digit1[MAX_LINE], digit2[MAX_LINE];
        int len1 = 0, len2 = 0;

        memset(digit1, 0, sizeof(digit1));
        memset(digit2, 0, sizeof(digit2));
        len1 = toString(tmp1, digit1);
        len2 = toString(tmp2, digit2);

        int ans[MAX_LINE];
        memset(ans, 0, sizeof(ans));

        for (int i = 0; i < len1; i++)
            for (int j = 0; j < len2; j++)
                ans[i + j] += digit1[i] * digit2[j];
        ans[0] += 2;

        int up = 0;
        for (int i = 0; i < len1 + len2 + 2; i++) {
            int tmp = up + ans[i];
            ans[i] = tmp % 10;
            up = tmp / 10;
        }

        int top = MAX_LINE;
        for (; top > 0 && ans[top - 1] == 0; top--);

        printf("Case #%d: ", K);
        for (int i = top - 1; i >=0 ; i--)
            printf("%d", ans[i]);
        puts("");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值