zoukankan      html  css  js  c++  java
  • 洛谷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 ;
    }
    
  • 相关阅读:
    Vue 单向数据流&双向数据绑定原理
    Arguments对象
    类数组对象(array-like objects)
    ...theArgs剩余参数
    vue 深度选择器/deep/报错(标红)
    修改mandMobile下拉菜单样式
    PC端input maxlength 失效问题
    el-input 正则限制输入为非负整数
    Mac鼠标左右键都是右键
    Vue双向数据绑定简易实现
  • 原文地址:https://www.cnblogs.com/Stephen-F/p/10618179.html
Copyright © 2011-2022 走看看