• 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
    ");
            }
        }
    }
  • 相关阅读:
    事半功倍系列 javascript(一)
    网页播放的视频代码
    显示消息提示对话框,并进行页面跳转
    GirdView不足10条显示为空行
    网页虚线效果
    JavaScript身份证号码验证支持新的带x身份证
    几个好用的ButtonCSS样式
    按钮超链接样式
    FlashCom学习第一课:了解名词、概念,安装FlashCom服务器。
    留住最后的激情,准备转向管理层的程序员们必看!
  • 原文地址:https://www.cnblogs.com/lfri/p/11296173.html
Copyright © 2020-2023  润新知