题目描述

https://www.nowcoder.com/practice/448127caa21e462f9c9755589a8f2416

题解

递归回溯法

回溯,即暴力穷举!(bushi…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

// 递归回溯
bool ishu(vector<int>& cards) {
if (cards.empty()) return true; // 递归结束条件
int cnt_first = count(cards.begin(), cards.end(), cards[0]);
// ----雀头----------------
if (cnt_first >= 2 && cards.size() % 3 != 0) { // 手牌数不是 3 的倍数说明当前还没有雀头
vector<int> newcards(cards.begin() + 2, cards.end());
//return ishu(newcards); // 不能在此 return false,下面一样,只能最后 return false
// 因为如果这里 ishu(newcards) 是 false 只是说明不能作为雀头,但是还有 刻子 或 顺子 的可能
if (ishu(newcards)) return true;
}
// ----刻子----------------
if (cnt_first >= 3) {
vector<int> newcards(cards.begin() + 3, cards.end());
if (ishu(newcards)) return true;
}
// ----顺子----------------
if (count(cards.begin(), cards.end(), cards[0] + 1)
&& count(cards.begin(), cards.end(), cards[0] + 2)) {
vector<int> newcards(cards.begin() + 1, cards.end());
newcards.erase(find(newcards.begin(), newcards.end(), cards[0] + 1));
newcards.erase(find(newcards.begin(), newcards.end(), cards[0] + 2));
if (ishu(newcards)) return true;
}
return false; // 剩下的牌既不成雀头也没有刻子或顺子
}

bool hupai(vector<int>& cards, int i) {
if (count(cards.begin(), cards.end(), i) == 4) return false; // 每个数字最多 4 张牌
cards.push_back(i); // 加入并使序列有序
sort(cards.begin(), cards.end());
return ishu(cards);
}

int main() {
vector<int> cards(13, 0);
for (int i = 0; i < 13; i++)
cin >> cards[i];
vector<int> res;
for (int i = 1; i <= 9; i++) { // 穷举所有可能加入的牌
vector<int> copy_cards(cards); // 传引用会改变原数组,所以拷贝一份保留原数组
if (hupai(copy_cards, i))
res.push_back(i);
}
if (res.empty()) res.push_back(0);
for (int iter : res)
cout << iter << " ";
return 0;
}