1. 程式人生 > >【求助】華為OJ題 成都麻將胡牌規則

【求助】華為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;
	}

}