zoukankan      html  css  js  c++  java
  • ACM POJ 2245Lotto解题报告

    http://poj.org/problem?id=2245

    Lotto

    在玩德国游戏Lotto时,要从集合{12,……,49}中取出六个数。

    一个非常流行的玩法(尽管这种玩法并不能增加你赢的机会)是从这49个数字中取出k个数字(6<k)组成子集S。然后玩游戏的时候仅从S中取出数字。

    例如,当k=8S=12358132134时,有28种可能的游戏:

    [1,2,3,5,8,13][1,2,3,5,8,21][1,2,3,5,8,34][1,2,3,5,13,21],……,[3,5,8,13,21,34]

    编一个程序,读入k的值和集合S,打印仅从S中取数的所有可能游戏。

    输入

    输入文件包括一个或多个测试情形。

    每种情形一行,由多个整数组成,整数之间用空格分隔。行首整数即为k值(6<k<13)。

    接着是用于描述集合Sk个整数,全部以升序排列。

    k的位置输入零(0)即表示输入结束。

    输出

    对于每一个测试情形,打印出所有可能游戏,每个游戏一行。

    每个游戏中的数字必须以升序排列,每两个之间用一个空格分隔。而这些游戏要用类似于字典编纂的方式排序,也就是说,先对最低位排序,然后是第二低位,依次类推,就像输出举例中演示的那样。

    输入样例

    7 1 2 3 4 5 6 7
    8 1 2 3 5 8 13 21 34

    0

    输出样例

    1 2 3 4 5 6
    1 2 3 4 5 7
    1 2 3 4 6 7
    1 2 3 5 6 7
    1 2 4 5 6 7
    1 3 4 5 6 7
    2 3 4 5 6 7
     
    1 2 3 5 8 13
    1 2 3 5 8 21
    1 2 3 5 8 34
    1 2 3 5 13 21
    1 2 3 5 13 34
    1 2 3 5 21 34
    1 2 3 8 13 21
    1 2 3 8 13 34
    1 2 3 8 21 34
    1 2 3 13 21 34
    1 2 5 8 13 21
    1 2 5 8 13 34
    1 2 5 8 21 34
    1 2 5 13 21 34
    1 2 8 13 21 34
    1 3 5 8 13 21
    1 3 5 8 13 34
    1 3 5 8 21 34
    1 3 5 13 21 34
    1 3 8 13 21 34
    1 5 8 13 21 34
    2 3 5 8 13 21
    2 3 5 8 13 34
    2 3 5 8 21 34
    2 3 5 13 21 34
    2 3 8 13 21 34
    2 5 8 13 21 34
    3 5 8 13 21 34

     

     

     

    本题就是产生组合数的方法。

    #include<stdio.h>

    #include<iostream>

    using namespace std;

    #define  MAXN 20

    int p[MAXN];

    void print(int *a,int m)  //输出

    {

        int i,cnt;

        for(i=0;i<m-1;i++) {cnt=a[i];cout<<p[cnt]<<' ';}

        cnt=a[m-1];

        cout<<p[cnt]<<endl;

    }   

    //先是产生1234567......这样的组合数,再利用下标输出需要的组合数

     

    void GenComb(int *a,int n,int m)//产生下一个组合数

    {

        int i,j,t;

        print(a,m);

        for(j=m-1;j>=0;j--)

          if(a[j]<n-m+j+1)break;

        t=a[j];

        for(i=0;i<=m-j-1;i++)

          a[j+i]=t+i+1;

    }

    void GenAllComb(int *a,int n,int m)

    {

        int index;

        for(index=0;index<m;index++)a[index]=index+1;//初始化,产生123...这样的数列

        index=0;

        while(index<=n-m)//index指向的是第一个组合数 的小标,当index大于n-m时说明,已经到达尾部。

        {

            GenComb(a,n,m);

            if(a[0]>index+1)index++;

        }   

    }  

    int main()

    {

        int n,m=6,a[MAXN],i;

        int first=0;//POJ上的题目要求最后一个不要产生空格,故除第一组外其余前面产生空格

        while(cin>>n,n)

        {

            if(first)  cout<<endl;

            first=1;

            for(i=1;i<=n;i++)  cin>>p[i];

            GenAllComb(a,n,m);

           

        }

        return 0;   

    }   

    (此程序在POJGCC++通不过,用C++,Accept了。。。 奇怪了)

    #include<stdio.h>
    #include
    <iostream>
    using namespace std;
    #define MAXN 20
    int p[MAXN];
    void print(int *a,int m) //输出
    {
    int i,cnt;
    for(i=0;i<m-1;i++) {cnt=a[i];cout<<p[cnt]<<' ';}
    cnt
    =a[m-1];
    cout
    <<p[cnt]<<endl;
    }
    //先是产生1,2,3,4,5,6,7......这样的组合数,再利用下标输出需要的组合数

    void GenComb(int *a,int n,int m)//产生下一个组合数
    {
    int i,j,t;
    print(a,m);
    for(j=m-1;j>=0;j--)
    if(a[j]<n-m+j+1)break;
    t
    =a[j];
    for(i=0;i<=m-j-1;i++)
    a[j
    +i]=t+i+1;
    }
    void GenAllComb(int *a,int n,int m)
    {
    int index;
    for(index=0;index<m;index++)a[index]=index+1;//初始化,产生1,2,3...这样的数列
    index=0;
    while(index<=n-m)//index指向的是第一个组合数 的小标,当index大于n-m时说明,已经到达尾部。
    {
    GenComb(a,n,m);
    if(a[0]>index+1)index++;
    }
    }
    int main()
    {
    int n,m=6,a[MAXN],i;
    int first=0;//POJ上的题目要求最后一个不要产生空格,故除第一组外其余前面产生空格
    while(cin>>n,n)
    {
    if(first) cout<<endl;
    first
    =1;
    for(i=1;i<=n;i++) cin>>p[i];
    GenAllComb(a,n,m);

    }
    return 0;
    }
     

    下面的程序是学习了网上的写出来的,比较简洁,推荐!!!

    #include<stdio.h>
    #include<string.h>//memset函数头文件
    int K;//每一组数的个数
    int num[13];
    int chosed[13];
    void find(int st,int n)
    {
        int i,first;
        if(n==6)
        {
            first=1;
            for(i=0;i<K;i++)
            {
                if(chosed[i])
                {
                    if(first==1) {printf("%d",num[i]);first=0;}
                    else printf(" %d",num[i]);
                }    
            }
            printf("\n");return;    
        }
        for(i=st;i<K;i++)
        {
            if(!chosed[i])
            {
                chosed[i]=1;
                find(i+1,n+1);
                chosed[i]=0;
            }    
        }        
    } 
    int main()
    {
        int i,first=1;
        while(scanf("%d",&K)!=EOF&&K)
        {
            for(i=0;i<K;i++) scanf("%d",&num[i]);
            if(first==1)first=0;
            else printf("\n");
            memset(chosed,0,sizeof(chosed));
            find(0,0);
        }  
        return 0;  
    }  
    
  • 相关阅读:
    php字符串相加
    elementUI的input输入一个字符就失去焦点问题
    js鸡尾酒排序算法
    js快速排序算法
    js冒泡排序算法改进
    js实现队列
    EXIF.js 读取图片的方向
    new Image().src资源重复请求问题
    canvas绘制圆图输出图片格式
    去掉"You are running Vue in development mode"提示
  • 原文地址:https://www.cnblogs.com/kuangbin/p/2114421.html
Copyright © 2011-2022 走看看