首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >组成30个人的小组

组成30个人的小组
EN

Stack Overflow用户
提问于 2012-08-27 03:45:39
回答 1查看 190关注 0票数 1

我想写一个程序,可以提供三个人的一系列组,这样没有人在组中与同一个人两次。所以我们不能在两个不同的系列中有123和124!

例如:9个人。它可以形成四次(绝对最大值):

系列1:

第一组:1 2 3

第二组:4 5 6

第三组:7 8 9

系列2:

第一组:1 5 9

第二组:2 6 7

第三组:3 4 8

系列3:

组1 3 5 7

第二组:1 6 8

第三组:2 4 9

系列4:

第一组:3 6 9

第二组:2 5 8

第三组:1 4 7

但只有12个人,我发现很难手工完成。可以形成4-5个12人的系列(绝对最大)。

我就是不知道怎么写这个程序。除了用笔和纸“尝试”之外,我找不到一个系统的方法来做这件事。我想和30个人一起做。30人可组成13-14个系列。(绝对最大值)

EN

回答 1

Stack Overflow用户

发布于 2012-08-27 03:58:36

好的,这是一个使用c++的回溯解决方案:

代码语言:javascript
复制
#include <stdio.h>

using namespace std;

int v[100], n;
int ma[100][100];

void init(int k)
{
    v[k] = 0;
}

bool solutionReached( int k ) 
{
    if (k == n + 1)
        return true;
    return false;
}

void printSolution( int k ) 
{
    for (int i = 1; i < k; i++)
    {
        printf("%i ", v[i]);
        if (i % 3 == 0)
        {
            printf("\n");
        }
    }

    for (i = 1; i < n; i++)
    {
        if (i % 3 == 1)
        {
            for (int j = i + 1; j < i + 3; j++)
            {
                ma[v[i]][v[j]] = 1;
                ma[v[j]][v[i]] = 1;
            }
        }

        for (int j = i + 1; j % 3 == 0; j++)
        {
            ma[v[i]][v[j]] = 1;
            ma[v[j]][v[i]] = 1;
        }
    }

    for (i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            //printf("%d ", ma[i][j]);
        }
        //printf("\n");
    }

    printf("\n");
}

bool hasSuccesor( int k ) 
{
    if(v[k] < n)
    {
        v[k]++;
        return true;
    }
    return false;
}

bool isValid( int k ) 
{
    for (int i = 1; i < k; i++)
    {
        if (v[i] == v[k])
        {
            return false;
        }

        /*if (ma[v[i]][v[k]] == 1)
        {
            return false;
        }*/
    }

    for (i = 1; i < k; i++)
    {
        if (i % 3 == 1)
        {
            for (int j = i + 1; j < i + 3; j++)
            {
                if (ma[v[i]][v[j]] == 1)
                {
                    return false;
                }
            }
        }

        for (int j = i + 1; j % 3 == 0; j++)
        {
            if (ma[v[i]][v[j]] == 1)
            {
                return false;
            }
        }
    }

    return true;
}

void bkt(int k)
{
    if(solutionReached(k))
        printSolution(k);
    else
    {
        init(k);
        while(hasSuccesor(k))
            if(isValid(k))
                bkt(k + 1);
    }
}

int main(int argc, char* argv[])
{
    n = 9;
    bkt(1);

    return 0;
}

如果您想进行实验,可以将n = 9更改为任何除以3的数字,如12, 15, 21,但即使是小数字(>15)也需要很长时间(这取决于计算机)。

编辑:我重做了一次,这样“没有人和同一个人在同一个组中两次”,但我只能找到3个组,而不是4个组,9个人。

例如:-对于9个程序提供:

代码语言:javascript
复制
1 2 3 
4 5 6 
7 8 9 

1 4 7 
2 5 8 
3 6 9 

1 5 9 
2 6 7 
4 3 8 

对于12个计划提供:

代码语言:javascript
复制
1 2 3 
4 5 6 
7 8 9 
10 11 12 

1 4 7 
2 5 10 
3 8 11 
6 9 12 

1 5 8 
2 4 12 
3 9 10 
7 6 11 

对于15:

代码语言:javascript
复制
1 2 3 
4 5 6 
7 8 9 
10 11 12 
13 14 15 

1 4 7 
2 5 8 
3 10 13 
6 11 14 
9 12 15 

1 5 9 
2 4 10 
3 6 15 
7 11 13 
8 12 14 

1 6 8 
2 7 14 
4 12 13 
5 10 15 
11 3 9 

18岁:(一分半钟后-所以还有更多-)

代码语言:javascript
复制
1 2 3 
4 5 6 
7 8 9 
10 11 12 
13 14 15 

1 4 7 
2 5 8 
3 10 13 
6 11 14 
9 12 15 

1 5 9 
2 4 10 
3 6 15 
7 11 13 
8 12 14 

1 6 8 
2 7 14 
4 12 13 
5 10 15 
11 3 9 

1 2 3 
4 5 6 
7 8 9 
10 11 12 
13 14 15 
16 17 18 

1 4 7 
2 5 8 
3 6 9 
10 13 16 
11 14 17 
12 15 18 

1 5 9 
2 4 10 
3 7 11 
6 13 18 
8 15 17 
14 12 16 

1 6 8 
2 7 12 
3 4 13 
5 10 17 
9 14 18 
11 15 16 

1 10 14 
2 6 15 
3 5 12 
4 9 16 
7 13 17 
8 11 18 

如果要将它们保存到文件中,请包含fstream并将printSolution修改为:

代码语言:javascript
复制
        void printSolution( int k ) 
    {
        ofstream cout;
        cout.open("date.txt", ios::app);

        for (int i = 1; i < k; i++)
        {
            cout << v[i] << " ";
            if (i % 3 == 0)
            {
                cout << "\n";
            }
        }

        for (i = 1; i < n; i++)
        {
            if (i % 3 == 1)
            {
                for (int j = i + 1; j < i + 3; j++)
                {
                    ma[v[i]][v[j]] = 1;
                    ma[v[j]][v[i]] = 1;
                }
            }

            for (int j = i + 1; j % 3 == 0; j++)
            {
                ma[v[i]][v[j]] = 1;
                ma[v[j]][v[i]] = 1;
            }
        }
     }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12133323

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档