环形划分

环形划分

在这里插入图片描述

题解

根据Hint可知,如果点数大于2就一定存在3元环废话
考虑如何构造这么多3元环。
由于最多只能有 n − 1 n-1 n1条边可以不参与3元环的形成,其它的边都需要找到一个3元环。
相当于给每个边匹配一个点,为了尽量使所有的3元环都是唯一的,这样更容易构造,我们得找到一种方法使得 i , j , k i,j,k i,j,k的关系是唯一的,即通过其中任意两个只能得到另外一个。
这样的构造方法有什么呢,和不变呀。
但对于任意两个点它们的和值是在 ( 1 , 2 n − 1 ) (1,2n-1) (1,2n1)中的,所以,对于加起来大于等于 n n n的,它们的和值就应该是 2 n 2n 2n,小于 n n n的和值就应该是 n n n
转化一下就是 i + j + k ≡ 0 ( m o d   n ) i+j+k\equiv 0 (mod\, n) i+j+k0(modn)
由于匹配过程中 j = ( 2 n / n ) − i j=(2n/n)-i j=(2n/n)i的时候会出现 i i i k k k相等的情况,刚好有 n − 1 / n − 2 n-1/n-2 n1/n2条边不能用。
我们直接暴力找满足条件的点对 ( i , j ) (i,j) (i,j)即可。

时间复杂度 O ( n 2 ) O(n^2) O(n2)

源码

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define MAXN 1000005
#define lowbit(x) (x&-x)
#define reg register
typedef long long LL;
typedef unsigned long long uLL;
typedef unsigned int uint;
typedef pair<int,int> pii;
const int INF=0x7f7f7f7f;
const int mo=1e9+7;
const double PI=acos(-1.0);
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
	_T f=1;x=0;char s=getchar();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
	x*=f;
}
int n,sum,tot;
struct ming{int x,y,z;}a[MAXN];
signed main(){
	freopen("circle.in","r",stdin);
	freopen("circle.out","w",stdout);
	read(n);
	for(int i=1;i<n;i++)
		for(int j=i+1;j<n;j++){
			int k=(2*n-i-j)%n;if(!k)k+=n;
			if(k!=i&&k!=j&&i!=j&&j<k)
				if(i<j&&j<k)a[++tot]=(ming){i,j,k};
		}
	if(n*(n-1)/2-n+1<=tot*3){
		puts("Yes");printf("%d\n",tot);
		for(int i=1;i<=tot;i++)
			printf("%d %d %d\n",a[i].x,a[i].y,a[i].z);
	}
	else puts("No");
	return 0;
}

谢谢!!!

posted @ 2021-04-05 14:51  StaroForgin  阅读(24)  评论(0)    收藏  举报  来源