【求助】华为OJ题 成都麻将胡牌规则

描述:

说起麻将,那可是川渝市民的最爱,无论亲朋好友聚会,还是业务谈判,总是少不了麻将的声音。
成都麻将只能包括3种类型:条,筒,万。没有“门、东南西北、红中”。
每种牌都是数字从1到9,每个数字有4张,共36张。筒,万,条均一样。
胡牌简化规则如下:

1.必须有一个对子,即两张相同的牌,比如:两个2筒,两个4条等。
2.剩余的牌,每3张需要凑成一个有效牌,比如:3个一样的牌(3个2筒),或者3个顺子(1条2条3条),如果所有的牌都能够凑好,再满足规则2和1,有一个对子,并且所有的牌只有两种类型,那么就可以胡牌了。
3.假设牌不会出现碰的情况,即输入的牌肯定是13张。
4.输入牌肯定都是麻将牌,不用考虑异常输入;也不用考虑会输入“门”,“红中”等成都麻将中不会出现的牌。

5.条用T表示,D用D表示,万用W标识。

6.不用考虑输入的合法性,这个由函数的使用者保证。输入的牌为字符串,字母为大写的TDW”

 

要求根据13个已知输入,判断可以胡那几张牌。

 

运行时间限制:无限制
内存限制:无限制
输入:

输入13张麻将牌,如"1T8T6W6W5D4W1T3W6W2W5D6T1T"


 

输出:

输出胡牌个数和要胡的牌,

其中胡牌个数占一行输出,胡哪一张牌占一行输出,

胡多张牌,输出数促按照T/D/W的顺序从小到大排列(如1T5T6D7D3W8W)。
1
7T

样例输入:
1T8T6W6W5D4W1T3W6W2W5D6T1T
样例输出:
1
7T

我的想法是遍历所有牌,加入到这十三张牌中,判断是否是胡牌。如下程序,判定得106分(总分160),实在没找出错误,求大神

代码如下:

</pre><pre name="code" class="java">import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;


public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		int[] count = new int[27];//TDW排列
		int[] tmp = new int[27];//TDW排列
		List<String> huPai = new ArrayList<String>();
		for(int i=0;i<27;i++){
			count[i]=0;
		}
		Scanner cin = new Scanner(System.in);
		String line = cin.nextLine();
		int len = line.length();
		for(int i=0;i<len;i += 2){
			if(line.charAt(i+1)=='T'){
				int num = Integer.parseInt(line.charAt(i)+"")-1;
				count[num]++;
			}else if(line.charAt(i+1)=='D'){
				int num = Integer.parseInt(line.charAt(i)+"")-1;
				count[num+9]++;
			}else if(line.charAt(i+1)=='W'){
				int num = Integer.parseInt(line.charAt(i)+"")-1;
				count[num+9*2]++;
			}
		}
		
		for(int i=0;i<27;i++){
			count[i]++;
			for(int j=0;j<27;j++)
				tmp[j] = count[j];
			boolean flag = isHU(tmp);
			if(flag)
				huPai.add(translate(i));
			count[i]--;
		}
		System.out.println(huPai.size());
		for(String x:huPai)
			System.out.print(x);
	}

	private static String translate(int i) {
		// TODO Auto-generated method stub
		int n = i/9;
		int pre = i%9+1;
		String r = null;
		switch (n) {
		case 0:
			r = pre + "T";
			break;
		case 1:
			r = pre + "D";
			break;
		case 2:
			r = pre + "W";
			break;
		default:
			break;
		}
		return r;
	}

	private static boolean isHU(int[] count) {
		// TODO Auto-generated method stub
		boolean result = tryHU(count, 14);
		return result;
	}

	private static boolean tryHU(int[] count, int len) {
		// TODO Auto-generated method stub
		if(len==0)
			return true;
		if(len%3==2){//说明对牌没出现
			for(int i=0;i<27;i++){
				if(count[i]>=2){
					count[i] -= 2;
					if(tryHU(count, len - 2))
						return true;
					count[i] += 2;
				}
			}
		}
		else{
			//三个一样的
			for(int i=0;i<27;i++){
				if(count[i]>=3){
					count[i] -= 3;
					if(tryHU(count, len - 3))
						return true;
					count[i] += 3;
				}
			}
			//是否是顺子
			for(int i=0;i<27-2;i++){
				if(count[i]>0&&count[i+1]>0&&count[i+2]>0){
					count[i] -= 1;
					count[i+1] -= 1;
					count[i+2] -= 1;
					if(tryHU(count, len - 3))
						return true;
					count[i] += 1;
					count[i+1] += 1;
					count[i+2] += 1;
				}
			}
		}
		return false;
	}

}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值