【CSP】-- Lotto

Time Limit: 1 Seconds 

Memory Limit: 32768KB

Problem Description 

In a Lotto I have ever played, one has to select 6 numbers from the set {1,2,…,49}. A popular strategy to play Lotto - although it doesn’t increase your chance of winning - is to select a subset S containing k (k>6) of these 49 numbers, and then play several games with choosing numbers only from S. For example, for k=8 and S = {1,2,3,5,8,13,21,34} there are 28 possible games: [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]. 

Your job is to write a program that reads in the number k and the set S and then prints all possible games choosing numbers only from S.

Input Specification

The input file will contain one or more test cases. Each test case consists of one line containing several integers separated from each other by spaces. The first integer on the line will be the number k (6 < k < 13). Then k integers, specifying the set S, will follow in ascending order. Input will be terminated by a value of zero (0) for k. 

Output Specification

For each test case, print all possible games, each game on one line. The numbers of each game have to be sorted in ascending order and separated from each other by exactly one space. The games themselves have to be sorted lexicographically, that means sorted by the lowest number first, then by the second lowest and so on, as demonstrated in the sample output below. The test cases have to be separated from each other by exactly one blank line. Do not put a blank line after the last test case. 

Sample Input 

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

Sample Output

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

Problem Source

University of Ulm Local Contest 1996

【题目大意】

在我曾经玩过的一种对号码的纸牌游戏(乐透)里,玩家必须从{1,2,...,49}中选6个数。玩Lotto的一个流行的策略是(虽然它并不增添你赢的机会):就是从这49个数中,选出k(k>6)个数组成一个子集S,然后只从S里拿出牌来玩几局游戏。例如:k=8,S={1,2,3,5,8,13,21,34},那么有28场游戏:[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),然后是从小到大排列的k个整数,即子集S。当k位零时,输入结束。

【输出格式】

对于每组测试数据,输出所有可能的游戏,每个游戏占一行。游戏里数字按升序排列,数与数之间有一个空格。所有游戏也要按字典序排列,也就是,首先比较各局游戏的第一个数的大小,然后是第二个数的大小,依次类推,如下面的输出样例所示。不同的测试例之间用一个空行隔开。最后一组测试例之后没有空行。

【算法分析】

本题实现的是从一组数中挑选6个数的所有游戏组合,输出每个游戏里的数字按升序排列,所有的游戏还要按字典序排列。

实现的算法包括:深度优先搜索等。

但最为简单的办法是模拟。因为数字已经有序,所以从前往后挑选,这样挑选出的数字不仅是升序,而且是字典序。

                                          0   1   2   3   ...   n-6   n-5   n-4   n-3   n-2   n-1

依次在第  0~(n-6)个数字之间,挑选第一个数字,序号为 a。第二个数字是第一个数字的序号 a 加 1,依次挑选数字,一直挑选到第 n-5 个数字,序号为 b。依次类推。

#include<stdio.h>
int number[14];              //存放原始数据

int main(){
    int line = 0;   //空行标志
    int n;    //数字个数
    while(scanf("%d",&n) && n){
        if(line) printf("\n");
        for(int i=0; i<n; ++i)   //读取子集S
            scanf("%d",&number[i]);
        //模拟挑选数字,并输出结果
        for(int a=0; a<n-5; ++a)
        	for(int b=a+1; b<n-4; ++b)
        		for(int c=b+1; c<n-3; ++c)
       				for(int d=c+1; d<n-2; ++d)
       					for(int e=d+1; e<n-1; ++e)
      						for(int f=e+1; f<n; ++f)
            					printf("%d %d %d %d %d %d\n",number[a],number[b],number[c],number[d],number[e],number[f]);
		line = 1;
    }
}

【讲解补充】

① 注意理解六个for循环的意义,注意for循环叠用的效果及意义


 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值