• Codeforces 899C


    传送门:http://codeforces.com/contest/899/problem/C

    本题是一个数学问题——集合划分。

    将集合{1,2,...,n}划分成两个集合,使得两个集合的元素之和的绝对差值最小。

    首先,考虑最简单的操作:

    第1步:将元素1和n置入集合A

    第2步:将元素2和n-1置入集合B

    第3步:将元素3和n-2置入集合A

    ……

    i步:将元素in+1-i,当i为奇数时置入集合A,偶数时置入集合B

    ……

    n/2步:将元素n/2和n/2+1置入集合B

    如此,集合A中的元素之和与集合B中的元素之和相等,绝对差为0。

    为保证第n/2步将元素置入集合B,则应保证n是4的整数倍。

    于是,若n是4的整数倍,则划分的最小绝对差为0,集合A={1,n,3,n-2,...,n/2-1,n/2+2},集合B={2,n-1,4,n-3,...,n/2,n/2+1}。

    n不可被4整除,则可以考虑预处理{1,2,...,n}的前若干项构成的集合{1,2,...,x},之后再处理集合{x+1,...,n}。当然,为了使得集合{x+1,...,n}易于处理,应保证其项数n-x是4的整数倍。于是,x可以取n%4。

    以下是按照x值分类的预处理过程:

    ①若x=1,则预处理{1}:将1置入集合A,此时最小绝对差为1;

    ②若x=2,则预处理{1,2}:将1置入集合A,2置入集合B,此时最小绝对差为1;

    ③若x=3,则预处理{1,2,3}:将1和2置入集合A,3置入集合B,此时最小绝对差为0。

    之后,{x+1,...,n}的处理过程类似于最初提及的操作——可将集合{x+1,...,n}看作{1,...,n-x}中的每一个元素增加x得到的集合,其中n-x是4的整数倍。

    参考程序如下:

    #include <stdio.h>
    #define MAX_N 30010
    
    int a[MAX_N];
    
    int main(void)
    {
        int n;
        scanf("%d", &n);
        int x = n % 4;
        int cnt = 0;
        int dif;
        if (x == 0) dif = 0;
        else if (x == 1) {
            dif = 1;
            a[cnt++] = 1;
        }
        else if (x == 2) {
            dif = 1;
            a[cnt++] = 1;
        }
        else if (x == 3) {
            dif = 0;
            a[cnt++] = 1;
            a[cnt++] = 2;
        }
        for (int i = x + 1; i <= x + (n - x) / 2; i += 2) {
            a[cnt++] = i;
            a[cnt++] = n + x + 1 - i;
        }
        printf("%d
    %d", dif, cnt);
        for (int i = 0; i < cnt; i++)
            printf(" %d", a[i]);
        return 0;
    }
  • 相关阅读:
    SDNU 1219.sign up problem
    SDNU 1232.A*B Problem(高精度)
    Go操作MySQL
    BootStrap jQuery 在线cdn
    Go语言标准库之http/template
    Go语言基础之net/http
    Go语言基础之网络编程
    Go语言基础之单元测试
    Go语言基础之rand(随机数)包
    Go语言基础之并发
  • 原文地址:https://www.cnblogs.com/siuginhung/p/8053154.html
Copyright © 2020-2023  润新知