EOJ 3536. 蛇形矩阵(找规律)

Time limit per test: 2.0 seconds

Memory limit: 256 megabytes

蛇形矩阵是我最喜欢的矩阵之一。n 阶蛇形矩阵由前 n2 个正整数顺时针从外到内盘绕而成。

例如四阶具有如下形式:

1  2  3  4
12 13 14 5
11 16 15 6
10 9  8  7

五阶(奇数阶数)在中心位置略有不同:

1  2  3  4  5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

由于这种盘绕的方式过分诡异,无法简单的用数学语言表示。所以无聊又过分的出题人想让你算出这个矩阵每一行的和。

Input

输入一个整数 n (1n200 000)。

Output

输出 n n 个整数,依次为每一行的和。

Examples

Input
4
Output
10
44
48
34
Input
5
Output
15
76
91
88
55
Input
1
Output

1
解析:
下面一部分转自 点击打开链接

对应的蛇形矩阵如下

1  2  3  4  5  6  7  8 932 33 34 35 36 37 38 39 1031 56 57 58 59 60 61 40 1130 55 72 73 74 75 62 41 1229 54 71 80 81 76 63 42 1328 53 70 79 78 77 64 43 1427 52 69 68 67 66 65 44 1526 51 50 49 48 47 46 45 1625 24 23 22 21 20 19 18 17

第一行的和是S1 = 9*10/2=45

第二行前8位比第一行多31,第9位多1S2 = 31*8+1+S1=294

第三行第2位到第7位比第二行多23 1位少1,后1位多1正好抵消,第8位多1,所以S3 = 23*6+1+S2=433

第四行第3位到第6位比第三行多15 2位少1,后2位多1正好抵消,第7位多1,所以S4 = 15*4+1+S3=494

第五行第4位到第5位比第三行多7 3位少1,后3位多1正好抵消,第6位多1,所以S5 = 7*2+1+S4=509

 这是上面的前半部分的规律,从a = 4 * n - 54*9-5=31, b = n - 19-1=8)开始,a依次减8b依次减2

第六行比第五行前4位少1 4位多1,中间1位少3S6 =S5-1*3=506

第七行比第六行前3位少1 3位多1,中间3位少11 S7 =S6 - 3*11=473

第八行比第七行前2位少1 2位多1,中间5位少19 S8 =S7 - 5*19=378

第九行比第八行前1位少1 1位多1,中间7位少27 S9 =S8 - 7*27=189

后半部分的规律是从a = 3, b = 1开始,a依次加8 b依次加2

最后总结的规律就是上面n/2+(n%2==0?0:1)行 ans[i]=ans[i-1]+增量+1 (这个增量每次递减8)
剩余下面的行 ans[i]=ans[i-1]+增量  (这个增量每次递减8)
这里的启示就是规律题可以通过递推答案所求来找公式(这里就是递推每一行的递推式来找到规律的)
#include 

typedef long long int lli;

const int MAXN = 2e5+10;
lli ans[MAXN];


int main()
{
    lli n;
    scanf("%lld",&n);
    if(n==1)
    {
        printf("1\n");
    }
    else
    {

        lli w1=4*n-5;
        ans[1]=(n+1)*n/2;
        ans[2]=(9*n*n-17*n+12)/2;
        lli tn=n-1;
        lli tw=w1;
        for(lli i=3;i<=n/2+(n%2==0?0:1);i++)
        {
            tn-=2;
            tw-=8;
            ans[i]=tw*tn+ans[i-1]+1;
        }
        ans[n]=((2*n-1)+(3*n-2))*n/2;
        tn=n-2;
        tw=4*n-9;
        for(lli i=n-1;i>n/2+(n%2==0?0:1);i--)
        {

            ans[i]=ans[i+1]+tn*tw;
            tn=tn-2;
            tw=tw-8;
        }
        for(int i=1;i<=n;i++)
        {
            printf("%lld\n",ans[i]);
        }
    }
    return 0;
}

你可能感兴趣的:(思维题,ACM,acm专项训练)