static const vector publicPailib
{
101,102,103,104,105,106,107,108,109,110,
101,102,103,104,105,106,107,108,109,110,
101,102,103,104,105,106,107,108,109,110,
101,102,103,104,105,106,107,108,109,110,
201,202,203,204,205,206,207,208,209,210,
201,202,203,204,205,206,207,208,209,210,
201,202,203,204,205,206,207,208,209,210,
201,202,203,204,205,206,207,208,209,210
};
static const int kindpai = 555; //王赖牌
内含lua实现
字牌有大字40张小字40张,特殊玩法会带王赖。
我们再玩字牌的时候,打出一张牌的时候会思考接下来听什么牌:
现在有手牌:101 102 103 104 105 106 107 108 109 110 (桌低有跑牌要做将情况)
暂时先不考虑最小和牌胡息就会有以下组合听牌:
(101 102 103)(104 105 106)(107 108 109)听 110
(101 102 103)(104 105 106)(108 109 110)听 107
(101 102 103)(105 106 107)(108 109 110)听 104
(102 103 104)(105 106 107)(108 109 110)听 101
那用代码的形式我们该怎样实现呢?
这里先找出手牌中由3个牌组成的所有有效组合。
(101 102 103)(102,103,104)(103,104,105)(104,105,106)
(105,106,107)(106,107,108)(107,108,109) (108,109,110)
(102,107,110)
然后从有效组合中找出(手牌数除以3)组(101 102 103)(104 105 106)(107 108 109)
这样的有效牌组剩什么牌,再拿剩下的牌去判断听什么样的牌就行了。
有王赖的情况下会递归一层,用王赖替换掉可以组成有效牌型的牌,代码中做了很多优化,
不然纯穷举的话,时间复杂度会很高,特别是赖子很多情况下。
3张4张王的情况复杂度会很高。
4张王赖最高特殊情况用了27m,最低小于1秒。
王赖建议不要在工作中使用。
测试:
void test()
{
//vector handPokers = getRandziPai(9); //随机发牌
//handPokers.emplace_back(kindpai);
//handPokers.emplace_back(kindpai);
//handPokers.emplace_back(kindpai);
//handPokers.emplace_back(kindpai);
vector handPokers = { 101,101,101,104,105,106,107,108,109,110 };
handPokers.emplace_back(kindpai);
//vector handPokers = { 104,105,106,104,105,106,108,108,208,110,110,210,205,206,207,206,207,208 ,101,102,203};
map res;
int huxi = 0;
getTingPai(handPokers,res, huxi);
for (auto it = res.begin(); it != res.end(); it++)
{
cout << " ting:" << it->first << " hufen:" << it->second << endl;
}
}
int main() //算听啥
{
srand(time(unsigned(NULL)));
while (getchar())
{
auto start = std::chrono::system_clock::now();
test();
auto end = std::chrono::system_clock::now();
std::chrono::duration elapsed_seconds = end - start;
std::cout << "elapsed time: " << elapsed_seconds.count() << "sn";
}
getchar();
return 0;
}
测试结果: