1 条题解

  • 0
    @ 2025-8-24 21:17:31

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar qhr2023
    **

    搬运于2025-08-24 21:17:30,当前版本为作者最后更新于2025-03-13 22:28:45,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    solution

    一道构造。

    先假设已经有了 nn 个点的解,考虑推广到 n+2n+2 个点。

    因为 nn 个点内部是合法的,令 n+1n+1n+2n+2 到这 nn 个点的距离及 nn 个点到 n+1n+1n+2n+2 距离都不超过 22 即可。

    我们可以从 n+2n+2nn 个点都连一条边,nn 个点每个点都连一条到 n+1n+1 的边,n+1n+1 再连一条到 n+2n+2 的边,这样就是一种合法的 n+2n+2 的方案了。

    如下图,黑点是 nn 个点,红色是新加的 22 个点,我们先不管心 nn 个点内部怎么连。

    所以我们知道,只要 nn 个点有解,那 n+2n+2 个点也一定有解。

    故只要找到有解的最小奇数和偶数即可,11 个点时显然成立,所以奇数都有解,而最小的偶数通过手算是 66。这样就可以构造所有 1+2k1+2k6+2k6+2k 的解了,kk 是非负整数。

    实现方面,对于奇数,从 22 开始执行上述的连边即可;对于偶数,可以把前 66 个点的边连完,从 77 开始执行上述连边即可。下图是 n=6n=6 的解。

    code

    #include <bits/stdc++.h>
    using namespace std;
    int n, a[505][505];
    int main () {
    	cin >> n;
    	if (n==2||n==4) {
    		puts("NO");
    		return 0;
    	}
    	puts("YES");
    	if (n%2==0) 
    		a[1][2]=a[1][3]=a[1][4]=1,
    		a[2][3]=a[2][5]=a[2][6]=1,
    		a[3][4]=a[3][5]=a[3][6]=1,
    		a[4][5]=a[4][2]=a[5][6]=a[5][1]=a[6][1]=a[6][4]=1;
    	for (int i=(n%2?2:7); i<=n; a[i][i+1]=1, i+=2)
    			for (int j=1; j<i; ++j)
    				a[j][i]=a[i+1][j]=1;
    	for (int i=1; i<=n; ++i, cout << '\n')
    		for (int j=1; j<=n; ++j)
    			cout << a[i][j] << ' ';
    	return 0;
    }
    
    • 1

    信息

    ID
    11535
    时间
    1000ms
    内存
    512MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者