日更计划Day8 麻将

题目传送门

思路

发现数据范围允许我们枚举每一张牌作为听牌,并且可以枚举每个有可能成为对子的牌,所以直接枚举即可。由于枚举的数量较多,循环嵌套可以使用函数封装的办法。这样可以使代码更加简洁清晰。但是我没用

代码

/*
这一题的难点我认为在多层循环中的信息传递,如题,我用了两个信号变量--flag和outter,如果能够把内两层循环封装进函数内,会清晰且方便许多。 
*/
#include<bits/stdc++.h>
using namespace std;
const int N = 500;
int vis[N],Count[N], ori[N];
int n,m,a,yon = 0; 
int main(){
	cin >> n >> m;
	for (int i = 1; i <= 3*m+1; i++){
		cin >> a;
		Count[a]++; 
		ori[a]++;
	}
	for (int i = 1; i <= n; i++){
		//枚举听牌
		int outter = 0;
		ori[i]++;
		for (int j = 1; j <= n; j++){
			if (outter == 1) break;
			int flag = 0;
			//枚举对子
			if (ori[j] >= 2){
				//有潜力成为对子
				ori[j] -= 2;			//先把对子取走 
				for (int k = 1; k <= n+2; k++) Count[k] = ori[k];		//到n+2的意义在于,如果n-1,n两个造成了后面小于零,那么也不可以成功凑成一队。 
				for (int k = 1; k <= n+2; k++){
				 	if (Count[k] < 0) {
				 		flag = 1;
				 		break;
					}
					Count[k] %= 3;			//取走刻字
					Count[k+1] -= Count[k];
					Count[k+2] -= Count[k]; 		//取走顺子 
				}
				ori[j] += 2; 
				if (flag == 0){
				 	outter = 1;
				} 
			} 
			
		}
		if (outter == 1){
			yon = 1;
			cout << i << " ";
		}
		ori[i]--;
	}
	if (yon == 0) cout << "NO";
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值