中国麻将(Chinese Mahjong, UVa 11210)【JAVA算法实现】

来源:互联网 发布:58应聘的淘宝模特 编辑:程序博客网 时间:2024/05/16 08:58

题目描述

麻将是一个中国原创的4人玩的游戏。这个游戏有很多变种,但本题只考虑一种有136张牌的玩法。这136张牌所包含的内容如下。

饼(筒)牌:每张牌包括一系列点,每个点代表一个铜钱。本题中用1T、2T、3T、4T、5T、6T、7T、8T、9T表示。

索(条)牌:每张牌由一系列竹棍组成,每根棍代表一挂铜钱。本题中用1S、2S、3S、4S、5S、6S、7S、8S、9S表示。

万牌:每张牌代表一万枚铜钱,如图1-14所示。本题中用1W、2W、3W、4W、5W、6W、7W、8W、9W表示。

风牌:东、南、西、北风。本题中用DONG、NAN、XI、BEI表示。

箭牌:中、发、白。本题中用ZHONG、FA、BAI表示。

总共有9×3+4+3=34种牌,每种4张,一共有136张牌。

其实麻将中还有如图1-17所示的8张花牌,所以共有136 + 8 = 144张牌,但是本题中不予考虑。

中国麻将的规则十分复杂,本题中只需考虑部分规则。在本题中,手牌(即每个人手里的牌)总是有13张。如果多了某张牌以后,整副牌可以拆成一个将(两张相同的牌)、0个或多个刻子(3张相同的牌)和0个或多个顺子(3张同花相连的牌。注意,风牌和箭牌不能形成顺子),我们就说这手牌“听”这张牌,即拿到那张牌以后就赢了,称为“和”(实战中还要考虑番数和特殊和法,在本题中可以忽略)。

输入格式

输入数据最多50组。每组数据由一行13张牌给出,输入保证给出的牌是合法的。输入结束标记为一行单个0。

输出

对于每组数据,输出所有“听”的牌,按照描述中的顺序列出(1T-9T,1S-9S,1W-9W,DONG,NAN,XI,BEI,ZHONG,FA,BAI)。每张牌最多被列出一次。如果没有“听”牌,输出Not ready。

样例输入

1S
1S
2T
2T
2T
3S
3S
3S
4T
4T
4T
5S
5S

样例输出

Case:1
1S

5S

import java.util.Arrays;import java.util.Scanner;public class Main {private final static String[] mahjong = { "1T", "2T", "3T", "4T", "5T","6T", "7T", "8T", "9T", "1S", "2S", "3S", "4S", "5S", "6S", "7S","8S", "9S", "1W", "2W", "3W", "4W", "5W", "6W", "7W", "8W", "9W","DONG", "NAN", "XI", "BEI", "ZHONG", "FA", "BAI" };private static int[] c = new int[34];// 只在预处理调用,因此速度无关紧要// 麻将列序号public static int convert(String s) {for (int i = 0; i < 34; i++)if (s.equals(mahjong[i]))return i;return -1;}// 回溯法递归过程// 遍历判断顺子和刻子,每当判断成立,相应麻将牌c[i]减一,继续递归调用search(int dep),若和了,那么dep=3。private static boolean search(int dep) {int i;// 判读刻子for (i = 0; i < 34; i++)if (c[i] >= 3) {if (dep == 3)return true;c[i] -= 3;if (search(dep + 1))return true;c[i] += 3;}// 判断顺子for (i = 0; i <= 24; i++)if (i % 9 <= 6 && c[i] >= 1 && c[i + 1] >= 1 && c[i + 2] >= 1) {if (dep == 3)return true;c[i]--;c[i + 1]--;c[i + 2]--;if (search(dep + 1))return true;c[i]++;c[i + 1]++;c[i + 2]++;}return false;}// 判断是否和了// 暴力找出所有的将牌,再根据各个将牌找出刻子和顺子。private static boolean check() {int i;for (i = 0; i < 34; i++) {if (c[i] >= 2) {c[i] -= 2;if (search(0))return true;c[i] += 2;}}return false;}public static void main(String[] args) {int caseno = 0, i, j;boolean ok;String s;int mj[] = new int[15];Scanner cin = new Scanner(System.in);while (cin.hasNext()) {s = cin.nextLine();if (s.charAt(0) == '0')break;System.out.print("Case:" + (++caseno));mj[0] = convert(s);for (i = 1; i < 13; i++) {s = cin.nextLine();mj[i] = convert(s);// System.out.println(mahjong[mj[i]]);}ok = false;for (i = 0; i < 34; i++) {Arrays.fill(c, 0);// 清零for (j = 0; j < 13; j++)c[mj[j]]++;if (c[i] >= 4)continue;c[i]++;//假设摸了这张牌if (check()) {//和了ok = true;System.out.println(mahjong[i]);//那么这副牌听这个牌}c[i]--;}if (!ok)System.out.println("not ready");System.out.println("\n");}}}


0 0
原创粉丝点击