洛谷P2668 斗地主
传送门
注意模拟的先后顺序
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#define re register
using namespace std ;
inline int read () {
int f = 1 , x = 0 ;
char ch = getchar () ;
while(ch < '0' || ch > '9') {if(ch == '-') f = -1 ; ch = getchar () ;}
while(ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + ch - '0' ; ch = getchar () ;}
return x * f ;
}
int card[16] ;
int n , m , ans ;
bool check() {
for(re int i = 1 ; i <= 14 ; ++ i)
if(card[i]) return false ;
return true ;
}
inline void dfs(int h) {
if(h > ans) {return ;}
if(check()) { ans = min(ans , h) ; }
int s1 = 0 , s2 = 0 , s3 = 0 , s4 = 0 ;
//s1:统计单牌 , s2:统计对子
for(re int i = 1 ; i <= 14 ; ++ i) {
if(card[i] == 1) s1 ++ ;
if(card[i] == 2) s2 ++ ;
}
//s4:统计四个的牌
//四带二的代码
for(re int i = 1 ; i <= 13 ; ++ i) {
if(card[i] == 4) {
s4 ++ ;
if(s1 >= 2) s1 -= 2 ; //四带二(带两个单牌)
else if(s2 >= 2) s2 -= 2 ; //四带二(带两个对子)
else if(s2 >= 1) s2 -- ; //四带二(带一个对子也就是两个相同的单牌)
}
}
//s3:统计三个的牌
for(re int i = 1 ; i <= 13 ; ++ i) {
if(card[i] == 3) {
s3 ++ ;
if(s1 >= 1) s1 -= 1 ; //三带一
else if(s2 >= 1) s2 -= 1 ; //三带一对
}
}
//ans:没有顺子情况下最小的排量
ans = min(ans , h + s1 + s2 + s3 + s4) ;
//是否有顺子
for(re int i = 1 ; i <= 8 ; ++ i) {
int j ;
for(j = i ; j <= 12 ; ++ j) {
card[j] -- ;
if(card[j] < 0) break ;
if(j - i + 1 >= 5)
dfs(h + 1) ;
}
if(j == 13) j -- ;
while(j >= i) card[j--]++ ;
}
for(re int i = 1 ; i <= 10 ; ++ i) {
int j ;
for(j = i ; j <= 12 ; ++ j) {
card[j] -= 2 ;
if(card[j] < 0) break ;
if(j - i + 1 >= 3)
dfs(h + 1) ;
}
if(j == 13) j -- ;
while(j >= i) card[j--] += 2 ;
}
for(re int i = 1 ; i <= 11 ; ++ i) {
int j ;
for(j = i ; j <= 12 ; ++ j) {
card[j] -= 3 ;
if(card[j] < 0) break ;
if(j - i + 1 >= 2)
dfs(h + 1) ;
}
if(j == 13) j -- ;
while(j >= i) card[j--] += 3 ;
}
}
int main () {
n = read () ; m = read () ;
while(n > 0) {
memset(card , 0 , sizeof(card)) ;
for(re int i = 1 ; i <= m ; ++ i) {
int x , y ;
x = read () ; y = read () ;
if(x == 1 || x == 2) {
card[11 + x] ++ ;
continue;
}
if(x == 0) {
card[14] ++ ;
continue ;
}
card[x - 2] ++ ;
}
ans = 24 ;
dfs(0) ;
printf("%d" , ans) ;
if(n != 1) cout << endl ;
n-- ;
}
return 0 ;
}
顺风不浪,逆风不怂。