#include #include #include #include enum majiangtype:uint8_t
;constexpr uint8_t mj(uint8_t m, uint8_t n)
inline majiangtype majiang_type(uint8_t m)
inline uint8_t majiang_value(uint8_t m)
enum emmj:uint8_t
;const std::setall_majiang_types = ;
//十三么牌型:13張再加其中任意一張
static const std::setpattern131 = ;
using majiangpai = std::vector;
template static t find_in_sorted(t begin, t end, v v)
else if (*it > v)
++it;
} return it;
}//遞迴拆分手牌
bool resolvepai(majiangpai pai, uint8_t joker_count)
else if (pai.size() + joker_count < 3)
if (pai.size() >= 3 && pai[0] == pai[2]) }
else if (pai.size() >= 2 && pai[0] == pai[1] && joker_count >= 1) }
else if (pai.size() >= 1 && joker_count >= 2) }
if (majiang_type(pai[0]) < emmjtype_zi)
else if(joker_count >= 1)
}else if(joker_count >= 1)
else if (joker_count >= 2)
}} return false;
}//普通和牌型別
bool iscommonhu(const majiangpai& original_pai)
pai = original_pai;
if (jiang_location != 0)
}//尋找將牌位置,記錄將牌第二個,並擦除該兩牌
jiang_location = 0;
for (; i < pai.size(); ++ i)
else if (pai[i] != emmj_joker && pai[0] == emmj_joker)
}if (jiang_location == 0)
//無賴子時可直接迴圈拆分,有賴子時較複雜一些,需要遞迴拆分
auto joker_end = pai.begin();
while (joker_end != pai.end() && *joker_end == emmj_joker)
uint8_t joker_count = joker_end - pai.begin();
if (joker_count > 0)
}else
else if (majiang_type(pai[0]) < emmjtype_zi)
else
}else
}else
}if (pai.empty())
}} return true;
}std::setis131ting(const majiangpai& original_pai)
auto pai_begin = original_pai.begin();
while (pai_begin != original_pai.end() && *pai_begin == emmj_joker)
uint8_t joker_count = pai_begin - original_pai.begin();
//先找將牌
auto it_jiang = pai_begin + 1;
while (it_jiang != original_pai.end())
++it_jiang;
} if (it_jiang == original_pai.end())
--joker_count;
++it2;
continue;
}++it1;
++it2;
} for (const auto& ting : pattern131)
return settingpai;
} //找到將牌,則如果是十三么就只能賴子個數加一張
auto pai = original_pai;
pai.erase(pai.begin() + (it_jiang - original_pai.begin()));
auto it1 = pai.cbegin() + joker_count;
auto it2 = pattern131.cbegin();
while(it1 != pai.cend() && it2 != pattern131.cend())
settingpai.insert(*it2);
++it2;
continue;
} ++it1;
++it2;
} if (it1 == pai.cend() && it2 != pattern131.cend())
return settingpai;
}std::setis7pairsting(const majiangpai& original_pai)
uint8_t joker_count = pai_begin - original_pai.begin();
for (; pai_begin != original_pai.end(); ++pai_begin)
else if(settingpai.size() > joker_count)
else
}if (pai_begin == original_pai.end() && settingpai.size() < joker_count)
}return settingpai;
}std::setcheckting(const majiangpai& pai)
ting_pai = is7pairsting(pai);
//小七對牌型與普通牌型相容,即可能和小七對,也可能普通和。
} //賴子個數:賴子牌編碼最小,在排好序的佇列前面
auto joker_end = pai.cbegin();
while (joker_end != pai.cend() && *joker_end == emmj_joker)
uint8_t jocker_count = joker_end - pai.cbegin();
for (auto i : all_majiang_types)
if (majiang_type(i) >= emmjtype_zi)
}else
);if (it == pai.cend())
}}
auto temp(pai);
auto range = std::equal_range(temp.begin(), temp.end(), i);
if (std::distance(range.first, range.second) == 4)
temp.insert(range.second, i);
if (iscommonhu(temp))
}return ting_pai;
}int main()
; auto ting = checkting(v);
for(auto i : ting)
return 0;
}
鬥地主含賴子的牌型判斷演算法
打出n張牌 可能含有賴子 需要判斷這n張牌能組成什麼牌型 對子 順子 飛機 整體思路 假設我們已經提前那種牌作為癩子。1 找出n張牌中的賴子,假設有m個賴子 2 計算出這剩餘n m張牌的牌值,存到和牌值一一對應的陣列,並記錄對應數量。3 計算剩餘牌能組成對應牌型所需要的賴子是否滿足需要。定義撲克陣列...
5180 帶限制的子串行和
可以利用雙向佇列進行視窗滑動 狀態方程 dp i 定義為 包含i的前i個數構成最大和 當然是滿足下標條件的最大和 dp i max dp i dp i j nums i j取值0 k 在這裡,每次回去尋找前面k個數中,哪個數構成和最大。迴圈過程中,前一次迴圈和本次的前k個數有k 1個數是相同的,利用...
LeetCode 5180 帶限制的子串行和
使用動態規劃,dp i 表示以i結束的最大子串行和,每個以i位置結束的有k 1個選擇,子串行只有這個元素或者從前面k個位置的某乙個位置接上。然後快速求前面k個的最大值,可以用到堆,從舊到新 從大到小佇列 struct node bool operator const node a,const nod...