2018 Tenka1 D - Crossing

Table of Contents

Problem description

Problem analysis

If N=3N=3, it can be seen that

1 2
2 3
3 1

satisfies the conditions. When N=4N=4 or N=5N=5, there are no subsets satisfying the conditions. If N=6N=6, result can be following

1 2 3
2 3 4
3 4 5
4 5 6

It can be assumed that every subset has same elements. Proof as following:

Assume NN has MM sets satisfy the conditions; ii-th of them is SiS_i. Set LiL_i is the number of SiS_i elements. Let L1L2LML_1 \leq L_2 \leq \ldots \leq L_M.

First, we consider LML_M. Because of condition

Any two of the sets S1,S2,,SkS_1, S_2, \ldots, S_k have exactly one element in common.

We kmow that L1=m1L_1=m-1 since each element in L1L_1 occur once from S2,,SMS_2, \ldots, S_M.

The other condition can be seen that

Each of the integers 1,2,,N1,2, \ldots, N contained excatly two of sets S1,S2,,SkS_1, S_2, \ldots, S_k.

It can be concluded that LM=m1L_M=m-1. So, it is 'OK' when 2N=(m1)m,m=2,3,,M2*N=(m-1)*m, m=2, 3, \ldots, M.

How shoule we order 1,2,,N1,2,\ldots,N? One of my solutions can be seen that

123m1m+1m+22m12m+12m3m3m12m23m4Nm2m13m3N\begin{matrix} 1 & 2 & 3 & \cdots & m \\ 1 & m+1 & m+2 & \cdots & 2*m-1 \\ 2 & m+1 & 2*m & \cdots & 3*m-3 \\ \vdots & \vdots & \vdots & \cdots & \vdots \\ m-1 & 2*m-2 & 3*m-4 & \cdots & N \\ m & 2*m-1 & 3*m-3 & \cdots & N \end{matrix}

AC code

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;

#define INF 0xc0c0c0c0
#define NINF 0x3f3f3f3f

#define FOR(i, a, b) for((i)=a; i<b; ++(i))
#define EFOR(i, a, b) for((i)=a; i>b; --(i))

#define MLC(n, type) (type*)malloc(n*sizeof(type))
#define CLC(n, type) (type*)calloc(n, sizeof(type))

#define MAXN 100000

void myPrint(int rows, int cols) {
	int i,j;
	int cur = 0;
	int end = 1;

	printf("%d\n", rows);

	for (i = 1; i <= rows; ++i) {
		printf("%d ", cols);
		for (j = 1; j < i; ++j) {
			if (j == 1) {
				printf("%d ", i-1);
				cur = i - 1;
			}
			else {
				cur += cols - j + 1;
				printf("%d ", cur);
			}
		}

		for (; j <= cols; ++end, ++j) {
			printf("%d ", end);
		}
		printf("\n");
	}
}

void solver(int n) {
	int i;

	int h = sqrt((n<<1));

	if (h*(h+1) != (n<<1)) {
		printf("No\n");
		return;
	}

	printf("Yes\n");
	myPrint(h+1, h);
}

int main() {
	int n;

	scanf("%d", &n);

	solver(n);

	return 0;
}