Tenka Programmer Contest D - Crossing / 构造(附带数学证明)

版权声明:All rights reserved. https://blog.csdn.net/qq_42814118/article/details/83473479

给定一正整数 N N 1 N 1 0 5 1 \le N \le 10^5 ),求是否存在一个集合的集合 T T 满足:

  • T N |T| \in N^*
  • S i T S i { 1 , 2 , 3 , . . . , N } \forall S_i \in T,S_i \subseteq \{1,2,3,...,N\}
  • i , j [ 1 , T ] \forall i,j \in [1,|T|] i j i \neq j S i S j = 1 |S_i \bigcap S_j|=1
  • i { 1 , 2 , 3 , . . . , N } \forall i\in \{1,2,3,...,N\} T T 中存在恰好两个不同的集合 S S S,S' 满足 i S i \in S i S i \in S'

如果存在这样的集合 T T ,请先输出 “Yes” (不含引号),
然后接下来一行输出一个正整数表示 T |T|
接下来 T |T| 行,每行先一个正整数,表示集合中的第 i i 个元素 S i S_i 的大小 S i |S_i|
接下来 S I |S_I| 个正整数,表示 S i S_i 中的元素。
如果不存在满足条件的集合 T T ,请输出“No”(不含引号)。
你只需要按照如上方法输出一个满足条件的 T T 即可。
S a m p l e   Sample\ :
输入:3
输出:
Yes
3
2 1 2
2 1 3
2 2 3

构造题。考场上不会证明,只会瞎猜。
手玩小数据,发现 1 1 可以, 3 3 可以, 6 6 可以,自然会想是不是满足 k ( k + 1 ) 2 k N \frac {k(k+1)}{2},k \in N^* 的数都可以。然后这类数有个好听的名字叫三角形数1,所以我就画了这样的三角形:

在这里插入图片描述

然后发现可以这样分:

在这里插入图片描述
(每个颜色代表一个集合)
这貌似是一种通解,于是我就写了这个代码,就过了,代码如下:

#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

#define R register
#define Maxn 100005

int main()
{
	R int n,sum=0;
	scanf("%d",&n);
	for (R int i=1;i<=n;++i)
	{
		sum += i;
		if(sum == n)
		{
			puts("Yes");
			printf("%d\n",i+1);
			R int j=1,cnt1=2;
			for (;j<=n;j+=cnt1,cnt1++)
			{
				printf("%d ",i);
				for (R int k=j-cnt1+2;k<=j;++k)printf("%d ",k);
				R int cnt2=cnt1-1;
				for (R int k=j+cnt2;k<=n;++cnt2,k+=cnt2)printf("%d ",k);
				puts("");
			}
			j=1,cnt1=2;
			printf("%d ",i);
			for (;j<=n;j+=cnt1,cnt1++)printf("%d ",j);
			return 0;
		}
	}
	puts("No");	
	return 0;
}

证明

但是我们不能只满足于猜结论!我们要严格证明!
我们接下来证明两个分结论,从而证明原题结论。

三角形数一定能构造出符合条件的集合T

引理1:若 k ( k 1 ) 2 \frac{k(k-1)}{2} 可以构造,并且构造出来的 T = k |T|=k ,那么 k ( k + 1 ) 2 \frac{k(k+1)}{2} 一定可以构造。
引理1证明:
设前者构造出来的集合组为
S 1 S_1
S 2 S_2
. . . ...
S k S_k
我们按照如下方法给每个集合添加一个数字
S 1 + { k ( k 1 ) 2 + 1 } S_1+\{\frac{k(k-1)}{2}+1\}
S 2 + { k ( k 1 ) 2 + 2 } S_2+\{\frac{k(k-1)}{2}+2\}
. . . ...
S k + { k ( k + 1 ) 2 } S_k+\{\frac{k(k+1)}{2}\}
我们添上的数都是两两不同的,所以这些集合还是满足两两公共元素恰好 1 个。
接下来,我们添的那些元素还要满足恰好出现在 2 个集合中,于是我们再构造一个集合
S k + 1 = { k ( k 1 ) 2 + 1 , k ( k 1 ) 2 + 2 , . . . , k ( k + 1 ) 2 } S_{k+1}=\{\frac{k(k-1)}{2}+1,\frac{k(k-1)}{2}+2,...,\frac{k(k+1)}{2}\}
这个集合和前面 k k 个集合的公共元素也都是恰好 1 个,并且 1 , 2 , . . . , k ( k + 1 ) 2 1,2,...,\frac{k(k+1)}{2} 这些数都恰好出现在 2 个集合中。因此这是一种合法的构造方案,因此引理1得证。
然后我们知道对于 1 1 显然可以构造出 T = 2 |T|=2 的满足条件的 T T ,这样我们根据数学归纳法就证明了原命题。

不是三角形数一定无法构造出满足条件的集合T

对于一个确定的 N N ,假设能构造出集合 T T
分析可知, S = N + k ( k 1 ) 2 \sum|S| = N+\frac{k(k-1)}{2} ,其中 k = T k=|T|
又根据已知条件, S = 2 N \sum|S| = 2N
联立,即 k 2 k 2 N = 0 k^2-k-2N=0 ,得 k = 1 + 8 N + 1 2 k=\frac{1+\sqrt {8N+1}}{2}
可以证明当且仅当 N N 为三角形数的情况下 k k 为整数,也就是说若 N N 不为三角形数,则不存在符合条件的 k k
因此原命题得证。


  1. 三角形数: https://baike.baidu.com/item/三角形数/5836794?fr=aladdin ↩︎

猜你喜欢

转载自blog.csdn.net/qq_42814118/article/details/83473479