小包最近迷上了一款叫做雀魂的麻将游戏,但是这个游戏规则太复杂,小包玩了几个月了还是输多赢少。
于是生气的小包根据游戏简化了一下规则发明了一种新的麻将,只留下一种花色,并且去除了一些特殊和牌方式(例如七对子等),具体的规则如下:
- 总共有36张牌,每张牌是1~9。每个数字4张牌。
- 你手里有其中的14张牌,如果这14张牌满足如下条件,即算作和牌
- 14张牌中有2张相同数字的牌,称为雀头。
- 除去上述2张牌,剩下12张牌可以组成4个顺子或刻子。顺子的意思是递增的连续3个数字牌(例如234,567等),刻子的意思是相同数字的3个数字牌(例如111,777)
例如:
1 1 1 2 2 2 6 6 6 7 7 7 9 9 可以组成1,2,6,7的4个刻子和9的雀头,可以和牌
1 1 1 1 2 2 3 3 5 6 7 7 8 9 用1做雀头,组123,123,567,789的四个顺子,可以和牌
1 1 1 2 2 2 3 3 3 5 6 7 7 9 无论用1 2 3 7哪个做雀头,都无法组成和牌的条件。
现在,小包从36张牌中抽取了13张牌,他想知道在剩下的23张牌中,再取一张牌,取到哪几种数字牌可以和牌。
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32M,其他语言64M
输入描述:
输入只有一行,包含13个数字,用空格分隔,每个数字在1~9之间,数据保证同种数字最多出现4次。
输出描述:
输出同样是一行,包含1个或以上的数字。代表他再取到哪些牌可以和牌。若满足条件的有多种牌,请按从小到大的顺序输出。若没有满足条件的牌,请输出一个数字0
示例1
输入例子:
1 1 1 2 2 2 5 5 5 6 6 6 9
输出例子:
9
例子说明:
可以组成1,2,6,7的4个刻子和9的雀头
示例2
输入例子:
1 1 1 1 2 2 3 3 5 6 7 8 9
输出例子:
4 7
例子说明:
用1做雀头,组123,123,567或456,789的四个顺子
示例3
输入例子:
1 1 1 2 2 2 3 3 3 5 7 7 9
输出例子:
0
例子说明:
来任何牌都无法和牌
这道题可以通过遍历每一种情况来解决。对于每一种情况,我们可以枚举最后一张牌的所有可能,然后判断是否满足和牌条件。
具体做法如下:
- 对于输入的13张牌,统计每种数字的出现次数。
- 对于每一种数字,判断其出现次数是否满足以下条件:
- 出现次数最多只能为1,即最多只能有一张这种数字的牌。
- 至少要有两张牌是不同的数字。
- 对于不满足上述条件的数字,直接输出0,表示无法和牌。
- 对于满足上述条件的数字,枚举最后一张牌的所有可能,然后判断是否满足和牌条件。
- 对于每一种可能的最后一张牌,判断其是否能够组成四个顺子或刻子。
- 如果能够组成四个顺子或刻子,并且当前数字的出现次数为1,那么输出该数字,表示可以取到该数字的牌来和牌。
下面是具体的实现代码:
c
1 | #include <iostream> |
2 | #include <vector> |
3 | using namespace std; |
4 | |
5 | int main() { |
6 | vector<int> nums(13); |
7 | int n; |
8 | cin >> n; |
9 | for (int i = 0; i < n; i++) { |
10 | cin >> nums[i]; |
11 | } |
12 | vector<int> cnt(10); |
13 | for (int i = 0; i < n; i++) { |
14 | cnt[nums[i]]++; |
15 | } |
16 | for (int i = 1; i <= 9; i++) { |
17 | if (cnt[i] > 1) { // 出现次数最多只能为1 |
18 | cout << "0" << endl; |
19 | return 0; |
20 | } |
21 | } |
22 | for (int i = 0; i < n; i++) { |
23 | for (int j = 1; j <= 9; j++) { |
24 | if (cnt[j] == 1 && (i == n - 1 || nums[i] != j)) { // 至少要有两张牌是不同的数字 |
25 | for (int k = i + 1; k < n; k++) { // 枚举最后一张牌的所有可能 |
26 | if (nums[k] == j) { // 能够组成四个顺子或刻子 |
27 | for (int m = i + 1; m < k; m++) { // 判断是否能够组成四个顺子或刻子 |
28 | if (nums[m] == nums[i]) continue; // 不是雀头 |
29 | if (nums[m] + 1 == nums[i]) continue; // 不是顺子 |
30 | if (nums[m] + 2 == nums[i]) continue; // 不是顺子 |
31 | if (nums[m] + 3 == nums[i]) continue; // 不是顺子 |
32 | if (nums[m] - 1 == nums[i]) continue; // 不是刻子(递减) |
33 | if (nums[m] - 2 == nums[i]) continue; // 不是刻子(递减) |
34 | if (nums[m] - 3 == nums[i]) continue; // 不是刻子(递减) |
35 | if (nums[m] - 4 == nums[i]) continue; // 不是刻子(递减) |
36 | cout << j << endl; // 可以取到该数字的牌来和牌 |
37 | } |
38 | } |
39 | } |
40 | } |
41 | } |
42 | } |
43 | cout << "0" << endl; // 没有满足条件的牌 |
44 | return 0; |
45 | } |