原题解链接:https://ac.nowcoder.com/discuss/150009

这里介绍一种可行的构造方法。首先在点(n,1)(n,1)(n3,0)(n-3,0)之间连一条线,之后依次连接(n,min(1+2k,n))(n, min(1 + 2k,n))(max(n32k,0),0),(kZ,k>0)(max(n-3- 2k,0),0), (k∈Z,k>0)直至1+2kn1+2k≥n并且n32k0n-3-2k≤0为止。 之后连接将以上画出的线按直线y=xy= x对称后的线段。最后连接(0,n1)(0,n-1)(n,n)(n,n)以及(n1,n)(n-1,n)(n,0)(n,0)

注意这种做法在nn较小时需要特判。

#include <bits/stdc++.h>
using namespace std;
#define mkpr make_pair
#define ft first
#define sd second

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;

template<class T>
inline void read(T &x) {
    x=0; int f=0; char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=1; if(ch==EOF) return; ch=getchar();}
    while(isdigit(ch)) {x=x*10+(ch-'0'); ch=getchar();} if(f) x=-x;
}

/***********************************************************/

int n;

int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        if(n==1) {
            printf("%d %d %d %d\n", 0, 0, 1, 1);
            printf("%d %d %d %d\n", 0, 1, 1, 0);
            continue;
        }
        if(n==2) {
            printf("%d %d %d %d\n", 0, 0, 1, 2);
            printf("%d %d %d %d\n", 0, 0, 2, 1);
            printf("%d %d %d %d\n", 0, 2, 2, 1);
            continue;
        }
        int x=2, y=n-3;
        while(x<=n || y>=0) {
            printf("%d %d %d %d\n", min(n, x), n, 0, max(y, 0));
            if(!(min(n, x)==n && max(y, 0)==0)) {
                printf("%d %d %d %d\n", n, min(n, x), max(y, 0), 0);
            }
            x+=2;
            y-=2;
        }
        printf("%d %d %d %d\n", 0, n-1, n, n);
        printf("%d %d %d %d", n-1, n, n, 0);
        if(T!=0) putchar('\n');
    }
    return 0;
}