解析
本题也算看了一半题解吧
看到“数学归纳法”退出来自己推的
这题想到归纳法后面也就简单了
首先,n=3和n=4的时候显然有解,可以打表
然后考虑在获得n-2的答案时,如何获得n的答案
如果n为奇数,我们可以把(1,n-1,2,n)、(3,n-1,4,n)…(n-4,n-1,n-3,n)各连两次,最后连两个(n-2,n-1,n)
如果n为偶数,我们可以把(1,n-1,2,n)、(3,n-1,4,n)…(n-5,n-1,n-4,n)各连两次,最后连一个(n-3,n-1,n-2,n)、(n-3,n-1,n)和(n-2,n-1,n)
然后…这道黑题就解决了…
(本人自己写了个checker,欢迎取用)
代码
#include<bits/stdc++.h>
const int N=2e6+100;
const int mod=1e9+7;
#define ll long long
using namespace std;
inline ll read() {
ll x(0),f(1);char c=getchar();
while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}
while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
int n,m;
int num[N],x[N],y[N],z[N],k[N],tot;
inline void add(int a,int b,int c){
++tot;x[tot]=a;y[tot]=b;z[tot]=c;num[tot]=3;
}
inline void add(int a,int b,int c,int d){
++tot;x[tot]=a;y[tot]=b;z[tot]=c;k[tot]=d;num[tot]=4;
}
void work(int n){
if(n==1) return;
if(n==4){
add(1,2,3);add(2,3,4);add(3,4,1);add(4,1,2);
return;
}
if(n&1){
for(int i=1;i<=n-3;i+=2) add(i,n-1,i+1,n),add(i,n-1,i+1,n);
add(n-2,n-1,n);add(n-2,n-1,n);
work(n-2);
}
else{
for(int i=1;i<=n-4;i+=2) add(i,n-1,i+1,n),add(i,n-1,i+1,n);
add(n-3,n-1,n);add(n-2,n-1,n);add(n-3,n-1,n-2,n);
work(n-2);
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read();
work(n);
//printf("%d ",n);
printf("%d\n",tot);
for(int i=1;i<=tot;i++){
printf("%d ",num[i]);
if(num[i]==3) printf("%d %d %d\n",x[i],y[i],z[i]);
else printf("%d %d %d %d\n",x[i],y[i],z[i],k[i]);
}
}
/*
1
281239
*/
checker
#include <cstdio>//checker by wind_whisper
#include <algorithm>
using namespace std;
#define ll long long
const int N = 1e6 + 10;
inline ll read() {
ll x(0),f(1);char c=getchar();
while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}
while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
int n,m;
int vis[900][900],x[5];
int main() {
freopen("a.out","r",stdin);
n=read();m=read();
for(int i=1;i<=m;i++){
int k=read();
for(int j=1;j<=k;j++){
x[j]=read();
if(j>1) vis[x[j]][x[j-1]]++,vis[x[j-1]][x[j]]++;
}
vis[x[1]][x[k]]++;vis[x[k]][x[1]]++;
}
for(int i=1;i<=n;i++){
for(int j=1;j<i;j++){
if(vis[i][j]!=2){
printf("WA! (%d %d) have %d edges\n",i,j,vis[i][j]);return 0;
}
}
}
printf("AC!\n");
return 0;
}