zoukankan      html  css  js  c++  java
  • 2019牛客多校E Androgynos——自补图&&构造

    题目

    给出一个 $n$,判断是否存在 $n$ 个顶点的自补图,如果存在,输出边和映射。

    分析

    一个无向图若同构于它的补图,则称该图为自补图

    定理:一个自补图一定存在 $4k$ 或 $4k+1$ 个顶点.

    证:

    原图的边数+补图的边数=完全图的边数=n(n-1)/2

    由于原图与补图同构,所以边数相等,

    所以,原图的边数=n(n-1)/4,

    边数肯定为整数,所以 4|n 或者 4|(n+1).

    现在的问题是如何构造呢?

    先考虑 $n=4k$,将其分成两半,

    一半连接成完全图,一半为独立的点,

    这样边数还不够,再将左上和右下一一相连,右上和左下一一相连。

    很容易发现其补图变形一下就跟它一样,然后找一下对应关系。

    #include<bits/stdc++.h>
    using namespace std;
    
    int n;
    
    int  main()
    {
        int T, kase=0;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d", &n);
            printf("Case #%d: ", ++kase);
            if(n % 4 == 0)
            {
                printf("Yes
    ");
                int k = n/4;
                for(int i = 1; i<= k;i++)
                {
                    for(int j = 1; j <= 2*k;j++)
                    {
                        if(j == i)   printf("0");
                        else   printf("1");
                    }
                    for(int j = 2*k+1;j <= 3*k;j++)  printf("0");
                    for(int j = 3*k+1;j <= 4*k;j++)  printf("1");
                    printf("
    ");
                }
                for(int i = k+1;i <= 2*k;i++)
                {
                    for(int j = 1; j <= 2*k;j++)
                    {
                        if(j == i)   printf("0");
                        else   printf("1");
                    }
                    for(int j = 2*k+1;j <= 3*k;j++)  printf("1");
                    for(int j = 3*k+1;j <= 4*k;j++)  printf("0");
                    printf("
    ");
                }
                for(int i = 2*k+1;i <= 3*k;i++)
                {
                    for(int j = 1;j <= k;j++)  printf("0");
                    for(int j = k+1;j <= 2*k;j++)  printf("1");
                    for(int j = 2*k+1;j <= 4*k;j++)  printf("0");
                    printf("
    ");
                }
                for(int i = 3*k+1;i <= 4*k;i++)
                {
                    for(int j = 1;j <= k;j++)  printf("1");
                    for(int j = k+1;j <= 2*k;j++)  printf("0");
                    for(int j = 2*k+1;j <= 4*k;j++)  printf("0");
                    printf("
    ");
                }
                for(int i = 4*k;i >= 3*k+1;i--)  printf("%d ", i);
                for(int i = 3*k;i >= 2*k+1;i--)  printf("%d ", i);
                for(int i = k;i >= 1;i--)  printf("%d ", i);
                for(int i = 2*k;i >= k+1;i--)  printf("%d%c", i, i == k+1? '
    ':' ');
            }
            else if(n % 4 == 1)
            {
                printf("Yes
    ");
                int k = n/4;
                for(int i = 1; i<= k;i++)
                {
                    for(int j = 1; j <= 2*k;j++)
                    {
                        if(j == i)   printf("0");
                        else   printf("1");
                    }
                    for(int j = 2*k+1;j <= 3*k;j++)  printf("0");
                    for(int j = 3*k+1;j <= 4*k;j++)  printf("1");
                    printf("1
    ");
                }
                for(int i = k+1;i <= 2*k;i++)
                {
                    for(int j = 1; j <= 2*k;j++)
                    {
                        if(j == i)   printf("0");
                        else   printf("1");
                    }
                    for(int j = 2*k+1;j <= 3*k;j++)  printf("1");
                    for(int j = 3*k+1;j <= 4*k;j++)  printf("0");
                    printf("1
    ");
                }
                for(int i = 2*k+1;i <= 3*k;i++)
                {
                    for(int j = 1;j <= k;j++)  printf("0");
                    for(int j = k+1;j <= 2*k;j++)  printf("1");
                    for(int j = 2*k+1;j <= 4*k;j++)  printf("0");
                    printf("0
    ");
                }
                for(int i = 3*k+1;i <= 4*k;i++)
                {
                    for(int j = 1;j <= k;j++)  printf("1");
                    for(int j = k+1;j <= 2*k;j++)  printf("0");
                    for(int j = 2*k+1;j <= 4*k;j++)  printf("0");
                    printf("0
    ");
                }
                for(int i = 1;i <= 2*k;i++)  printf("1");
                for(int i = 2*k+1;i <= 4*k+1;i++)  printf("0");
                printf("
    ");
    
                for(int i = 4*k;i >= 3*k+1;i--)  printf("%d ", i);
                for(int i = 3*k;i >= 2*k+1;i--)  printf("%d ", i);
                for(int i = k;i >= 1;i--)  printf("%d ", i);
                for(int i = 2*k;i >= k+1;i--)  printf("%d ", i);
                printf("%d
    ", 4*k+1);
            }
            else
            {
                printf("No
    ");
            }
        }
    }
  • 相关阅读:
    1、搭建CICD平台
    Jackson 的 基本用法
    多种方式实现动态替换Android默认桌面Launcher
    Springboot2.x整合Redis以及连接哨兵模式/集群模式
    Redis哨兵(Sentinel)模式
    redis的哨兵模式(redis有密码)
    【数据结构】——LCT(link cut tree)
    征战蓝桥 —— 2017年第八届 —— C/C++A组第3题——魔方状态
    征战蓝桥 —— 2017年第八届 —— C/C++A组第4题——方格分割
    征战蓝桥 —— 2017年第八届 —— C/C++A组第4题——方格分割
  • 原文地址:https://www.cnblogs.com/lfri/p/11296173.html
Copyright © 2011-2022 走看看