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 (1≤n≤200000)。
Output
輸出 n 行 n 個整數,依次為每一行的和。
Examples
Input4Output
10 44 48 34Input
5Output
15 76 91 88 55Input
1Output 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位多1,S2 = 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 - 5(4*9-5=31), b = n - 1(9-1=8
第六行比第五行前4位少1,後4位多1,中間1位少3,S6 =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 <cstdio>
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;
}