Math 30人一组

Math 30人一组,math,Math,我想写一个程序,可以提供一系列的3人小组,这样就没有人在同一个人小组两次。所以我们不能在两个不同的系列中有123和124 例如:9人。它可以形成四次(绝对最大值): 系列1: 第1组:12 3 第2组:45 6 第3组:7 8 9 系列2: 第一组:15 9 第2组:26 7 第3组:34 8 系列3: 第1组3 5 7 第2组:16 8 第三组:249 系列4: 第一组:36 9 第2组:2 5 8 第三组:14 7 但是仅仅有12个人,我发现用手很难做到。可以形成4-5个12人系列(绝对最

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

例如:9人。它可以形成四次(绝对最大值):
系列1:
第1组:12 3
第2组:45 6
第3组:7 8 9

系列2:
第一组:15 9
第2组:26 7
第3组:34 8

系列3:
第1组3 5 7
第2组:16 8
第三组:249

系列4:
第一组:36 9
第2组:2 5 8
第三组:14 7

但是仅仅有12个人,我发现用手很难做到。可以形成4-5个12人系列(绝对最大值)


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

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

#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;
}
对于12个项目,给出:

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 
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年:

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岁:(一分钟半后-因此还有更多-)

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

        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;
            }
        }
     }
void打印解决方案(int k)
{
流孔直径;
cout.open(“date.txt”,ios::app);
对于(int i=1;icout好的,下面是一个使用c++的回溯解决方案:

#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;
}
对于12个项目,给出:

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 
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年:

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岁:(一分钟半后-因此还有更多-)

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

        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;
            }
        }
     }
void打印解决方案(int k)
{
流孔直径;
cout.open(“date.txt”,ios::app);
对于(int i=1;i看起来不错!但是
1 2 3
4 5 6
7 8 9

1 2 3
4 5 6
7 9 8
是一样的!但是我想你误解了这个问题。你不能有1 2 3 4 5 6 7 8 9然后有1 2 3 4 5 7 6 8 9!任何人都不能再和同一个人一起来了!听起来很棒!非常感谢你!谢谢你你知道怎么编程序吗?酷!我刚用n=30开始了这个程序。你认为它会在晚上结束吗?看起来不错!但是
13
46
79

123
456
78
是一回事!但是我想你误解了这个问题。你不能有12345689然后有123894 5 7 6 8 9!任何人都不能再和同一个人一起组队!听起来很棒!非常感谢你知道如何编程吗?酷!我刚用n=30开始了这个程序。你认为它会在晚上完成吗?这个问题的可能重复是NP难的(这意味着你不会在任何合理的时间内为大量的人找到一个精确的解决方案),但上面的链接给出了答案。你认为30人生成是可能的吗?甚至可以手动生成吗?这个问题的可能重复是NP难的(这意味着你不会在任何合理的时间内为大量的人找到一个精确的解决方案),但上面的链接给出了答案。你认为有30人可以生成吗?甚至可以手工生成吗?