• 集合分解


    题目描述

    给你一个数字集合,问能否将集合中的数分成六个集合,且每个集合中的数字和相等。

    输入形式

    输入有多组测试数据,以整数T开始,表示T组测试数据,每个case以N开头,且N<=30,表示集合中数字的个数,接下来有N个整数。

    输出形式

    若可以分解,输出"yes",否则为"no"

    样例输入

    3

    20 1 2 3 4 5 5 4 3 2 1 1 2 3 4 5 5 4 3 2 1

    20 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

    9 1 2 4 3 3 5 6 6 6

    样例输出

    yes

    no

    #include <stdio.h>
    #include <iostream>
    #include <stdlib.h>
    #include <algorithm>
    using namespace std;
    int a[40];//存集合
    bool used[40] = { 0 };//是否使用过
    int T, n;//几组数据  几个数字
    int quarter;//记录平均数
    bool flag = false;//成功标志
    void Track(int, int);
    int cmp(const void *a, const void *b)
    {
        return *(int *)a - *(int *)b;
        //从小到大排序
    }
    void find(int num) {
        if (num > 6) {
            flag = 1;
            return;
        }
        int i;
        for (i = 1; i <= n; i++) {
            if (used[i] == 0) {
                used[i] = 1;
                Track(num,a[i]);
                used[i] = 0;//不成功则回退
            }
        }
    }//开始匹配第num个集合
    void Track(int num,int sum) {
        if (flag == true)
            return;
        int i;
        if (sum == quarter) {
            find(num + 1);
        }
        else {
            for (i = num + 1; i <= n; i++) {
                if (sum + a[i] <= quarter) {
                    if (used[i] == 0) {
                        used[i] = 1;
                        Track(num, sum + a[i]);
                        used[i] = 0;//不成功则回退
                    }
                }
                else
                    return;//之后的元素都超过quarter 直接return 剪枝
            }//每次只需引入当前元素之后的元素,强剪枝
        }
    }//匹配第num个集合
    int main() {
        cin >> T;
        while (T>0) {
            cin >> n;
            int i;
            int sum = 0;
            if (n < 6) {
                printf("no
    ");
                T--;
                continue;
            }
            for (i = 1; i <= n; i++) {
                cin >> a[i];
                sum += a[i];
                used[i] = 0;
            }
            qsort(a + 1, n, sizeof(a[1]), cmp);//注意数组a第一个元素不用
            quarter = sum / 6;
            if (sum % 6 != 0) {
                printf("no
    ");//数量上无法分成六份
                T--;
                continue;
            }
            if (a[n] > quarter) {
                printf("no
    ");//最大值大于sum/6
                T--;
                continue;
            }
            find(1);
            if (flag == 1)
                printf("yes
    ");
            else
                printf("no
    ");
            T--;
        }
        return 0;
    }
  • 相关阅读:
    展望未来,总结过去10年的程序员生涯,给程序员小弟弟小妹妹们的一些总结性忠告
    马士兵_JAVA自学之路(为那些目标模糊的码农们)
    Java知识点总结
    解决:对COM组件的调用返回了错误HRESULT E_FAIL
    平差方法
    二进制、八进制、十进制、十六进制之间转换
    解决电脑复选框图标不正确方法
    SQL语句中的Create
    字段的值转换为大小写
    SQL NOW() 函数
  • 原文地址:https://www.cnblogs.com/woxiaosade/p/10019520.html
Copyright © 2020-2023  润新知