环形划分
环形划分

题解
根据Hint可知,如果点数大于2就一定存在3元环废话
考虑如何构造这么多3元环。
由于最多只能有
n
−
1
n-1
n−1条边可以不参与3元环的形成,其它的边都需要找到一个3元环。
相当于给每个边匹配一个点,为了尽量使所有的3元环都是唯一的,这样更容易构造,我们得找到一种方法使得
i
,
j
,
k
i,j,k
i,j,k的关系是唯一的,即通过其中任意两个只能得到另外一个。
这样的构造方法有什么呢,和不变呀。
但对于任意两个点它们的和值是在
(
1
,
2
n
−
1
)
(1,2n-1)
(1,2n−1)中的,所以,对于加起来大于等于
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+k≡0(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
n−1/n−2条边不能用。
我们直接暴力找满足条件的点对
(
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;
}

浙公网安备 33010602011771号