很智慧的构造。
相当于我们要将 $\frac{n(n-1)}{2}$ 个数对 $(x,y)$ ,以一定方式放入给出的方格内。一个简单的想法是,将 $(x,y)$ 按照 $|x-y|$ 分类,再以一种加减交错的方式排在一起。按照 $|x-y|=i$ 分类之后,似乎正好与每一列的二元组的个数对应起来了。
更具体一点,我们对于每一个 $x$,构造 $x,x+1,x-1,x+2,x-2,\cdots$,直到不能构造为止。这样的形式恰好满足上面所有限制。最后按照序列长度排序即可。正确性看起来真的显然,但是确实很巧妙。
时间复杂度 $\mathcal O(n^2)$。
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
   | #include<iostream> #include<cstdio> using namespace std; const int N=4e3+10; int n,t; int a[N][N]; int rk[N]; int main() {     scanf("%d%d",&n,&t);     for(int i=1;i<=n;i++)     {         a[i][1]=i;         int cnt=1;         for(int j=1;j<=n;j++)         {             if(i+j>n)break;             a[i][++cnt]=i+j;             if(i-j<1)break;             a[i][++cnt]=i-j;         }         rk[cnt]=i;     }     for(int i=1;i<=n;i++,puts(""))for(int j=1;j<=i;j++)printf("%d ",a[rk[i]][j]);     return 0; }
   |