首页 > 其他 > 详细

洛谷P2668 斗地主

时间:2019-03-28 22:39:28      阅读:134      评论:0      收藏:0      [点我收藏+]

传送门

注意模拟的先后顺序

#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 ;
}

洛谷P2668 斗地主

原文:https://www.cnblogs.com/Stephen-F/p/10618179.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!