阿里測評題目:跑得快
題目描述
單牌:一張一張的出牌,大小順序是2>A>K>Q>J>10>9>8>7>6>5>4>3。
順子:5張以上連續的單牌,最大JQKA2,最小A2345
對子:成雙出牌,大小順序:2對>A對>K對>Q對>J對>10對>9對>8對>7對>6對>5對>4對>3對。
連對:兩個及以上相連的對子比如:2233 778899 其中2233也可以連,但是是最小的連隊,AA2233是最小的三連對。
三帶一:三張相同的牌可帶一張單牌,最大三個2,三個對應牌大過對方即可,帶1個的隨機。
炸彈:四個相同的牌,可以大過其他牌,最大四個2
爲簡化起見
1,輸入輸出,10用字符I表示,且所有字符都大寫
2,出牌時,對於能大過的請輸出最小的能大過的牌即可
3,本次答題可以暫不考慮三帶一規則
要求
編譯器版本: Java 1.8.0_66
請使用標準輸入輸出(System.in, System.out);已禁用圖形、文件、網絡、系統相關的操作,如java.lang.Process , javax.swing.JFrame , Runtime.getRuntime;不要自定義包名稱,否則會報錯,即不要添加package answer之類的語句;您可以寫很多個類,但是必須有一個類名爲Main,並且爲public屬性,並且Main爲唯一的public class,Main類的裏面必須包含一個名字爲’main’的靜態方法(函數),這個方法是程序的入口
時間限制: 3S (C/C++以外的語言爲: 5 S) 內存限制: 128M (C/C++以外的語言爲: 640 M)
輸入:
共2行 第一行是你最初抓的13張牌 第二行表示你上家出的牌
輸出:
如果能大過,則輸出你的出牌,否則輸出0
輸入範例:
6788999IJKKAA
3344
輸出範例:
8899
題目解析
其實這個題目相當的簡單,但是在40分鐘內編完也不是一件容易的事情,因爲代碼量還是比較大的。
首先考慮:
- 各種牌型大不過,就要考慮有沒有炸彈,如果有則出炸彈,否則出0
- 牌型分析:
- 單牌,1張
- 對子,2張
- 順子,5+
- 連對,偶數張,且都是成對出現,4+
- 三帶一,4張,3張一樣,一張不同
- 炸彈,4張一樣的
- 針對單牌和對子可以作爲一種情況考慮,考慮都是一個key,只不過一個是重複一次,一個是兩次
- 對於順子和連對也可以作爲一種情況考慮,考慮的就是一個連起來的數值集合,不同的是順子要求的是5+張連續的,只重複一次,而連對則是要求3+連續的,只重複離兩次。
- 按照34…JQKA2建立合適的映射,達到一個利用字符串比較牌型大小的結果。
代碼:
package Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Run {
public static final String ERROR = "0";
public static void main(String[] args) {
String data1 = "67KK889999IJKKAA";
String data2 = "A2345";
String result = runFast(data1, data2);
System.out.println(runFast(data1, data2));
}
/**
* 牌型分析:
* 1.單牌, 1張
* 2.對子, 2張
* 3.順子, 5+
* 4.連對,偶數張,且都是成對出現,4+
* 5.三帶一,4張,3張一樣
* 6.炸彈,4張,一樣
*
* @param data1
* @param data2
* @return
*/
public static String runFast(String data1, String data2) {
String[] booms = hasBoom(data1);
if (data2.length() == 1 || data2.length() == 2) {
return runFastOneOrTwo(data1, data2, booms);
} else if (data2.length() == 4) {
if (isBoom(data2)) {
return runFastBoom(data1, data2, booms);
} else if (isPair(data2)) {
return runFastPair(data1, data2, booms, 2);
}
return runFastThreeWithOne(data1, data2, booms);
} else if (isPair(data2)) {
return runFastPair(data1, data2, booms, 2);
}
//只剩下順子的情況
return runFastPair(data1, data2, booms, 1);
}
/**
*
* @param data1
* @param key
* @param length
* @return
*/
private static String getMin(String data1, char key, int length){
String encode = sortEveryChar(createMap(data1));
StringBuilder builder = new StringBuilder();
builder.append('0');
for (int i = 1; i < encode.length(); i++) {
int b = encode.charAt(i) - encode.charAt(i - 1);
if (b != 0){
builder.append('1');
}else {
builder.append('0');
}
}
String keyString = builder.toString();
int start = 0;
int end = 0;
for (int i = 0; i < keyString.length(); i++) {
end = keyString.indexOf('1', start + 1);
if (end == -1){
break;
}else if (encode.charAt(start) > key && end - start >= length){
return encode.substring(start, end);
}else{
start = end;
}
}
return null;
}
private static String runFastThreeWithOne(String data1, String data2, String[] booms) {
char key = getMultiOne(data2);
String result = getMin(data1, key, data2.length());
if (result != null){
String encode = sortEveryChar(createMap(data1));
if (result.charAt(0) == encode.charAt(0) && result.length() == 4){
return resolveMap(result);
}else if (result.charAt(0) == encode.charAt(0) && result.length() == 3){
return resolveMap(result + encode.charAt(3));
}else if (result.charAt(0) != encode.charAt(0)){
return resolveMap(result.substring(0, 3) + encode.charAt(0));
}
}else if (booms != null){
return resolveMap(booms[0]);
}
return ERROR;
}
private static char getMultiOne(String data2) {
String encode = sortEveryChar(createMap(data2));
return encode.charAt(1);
}
public static String asString(char[] arr){
StringBuilder builder = new StringBuilder();
for (char a :
arr) {
builder.append(a);
}
return builder.toString();
}
public static String generateString(char start, int length, int times){
StringBuilder builder = new StringBuilder();
for (int i = 0; i < length; i++) {
for (int j = 0; j < times; j++) {
char temp = (char) (start + i);
builder.append(temp);
}
}
return builder.toString();
}
private static String runFastPair(String data1, String data2, String[] booms, int threshold) {
String key = getKey(createMap(data1), 'B', 'N', threshold);
String dataKey = getKey(createMap(data2), 'B', 'N', threshold);
int keyLen = data2.length() / threshold;
char[] arr = new char[keyLen];
Arrays.fill(arr, '1');
String flag = asString(arr);
if (dataKey.contains(flag)){
//33++
int dest = dataKey.indexOf(flag);
int pos = key.indexOf(flag, dest + 1);
if (pos != -1){
char start = (char) (pos + 'B');
return resolveMap(generateString(start, keyLen, threshold));
}
}else if (dataKey.endsWith("11")){
if (key.startsWith(flag.substring(0, keyLen - 1))){
//2233的類型
return resolveMap(generateString('N', 1, threshold)
+ generateString('B', keyLen - 1, threshold));
}else{
int pos = key.indexOf(flag);
if (pos != -1){
char start = (char) (pos + 'B');
return resolveMap(generateString(start, keyLen, threshold));
}
}
}else if (dataKey.endsWith("1") && key.contains(flag)){
//2233
int pos = key.indexOf(flag);
char start = (char) (pos + 'B');
return resolveMap(generateString(start, keyLen, threshold));
}
return booms == null ? ERROR : resolveMap(booms[0]);
}
private static String getKey(String map, char start, char end, int threshold) {
String encode = sortEveryChar(map);
int[] arr = new int[end - start + 1];
for (int i = 0; i < encode.length(); i++) {
arr[encode.charAt(i) - 'B'] ++;
}
StringBuilder builder = new StringBuilder();
for (int anArr : arr) {
if (anArr >= threshold){
builder.append('1');
}else{
builder.append('0');
}
}
return builder.toString();
}
private static String runFastBoom(String data1, String data2, String[] booms) {
char key = createMap(data2).charAt(0);
if (booms != null){
for (int i = 0; i < booms.length; i++) {
if (booms[i].charAt(0) > key){
return resolveMap(booms[i]);
}
}
}
return ERROR;
}
private static String runFastOneOrTwo(String data1, String data2, String[] booms) {
String result = getMin(data1, createMap(data2).charAt(0), data2.length());
if (result != null){
return resolveMap(result.substring(0, data2.length()));
}else if (booms != null){
return resolveMap(booms[0]);
}
return ERROR;
}
public static String sortEveryChar(String src) {
char[] arr = src.toCharArray();
Arrays.sort(arr);
StringBuilder builder = new StringBuilder();
for (char anArr : arr) {
builder.append(anArr);
}
return builder.toString();
}
public static String[] hasBoom(String src) {
String encode = sortEveryChar(createMap(src));
List<String> result = new ArrayList<>();
for (int i = 0; i < encode.length() - 4; i++) {
String temp = encode.substring(i, i + 4);
if (isBoom(temp)) {
result.add(temp);
}
}
if (result.size() == 0){
return null;
}
String []arr = new String[result.size()];
for (int i = 0; i < result.size(); i++) {
arr[i] = result.get(i);
}
return arr;
}
public static boolean isBoom(String src) {
for (int i = 0; i < src.length(); i++) {
if (src.charAt(i) != src.charAt(0)) {
return false;
}
}
return true;
}
public static boolean isPair(String src) {
char a = 'A';
String encode = createMap(src);
for (int i = 0; i < encode.length(); i++) {
a ^= encode.charAt(i);
}
return a == 'A';
}
public static String createMap(String src) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < src.length(); i++) {
char temp = src.charAt(i);
if (temp >= '3' && temp <= '9') {
int c = temp - '3';
temp = (char) (c + 'B');
builder.append(temp);
} else if (temp == 'Q') {
builder.append('K');
} else if (temp == 'K') {
builder.append('L');
} else if (temp == 'A') {
builder.append('M');
} else if (temp == '2') {
builder.append('N');
}else{
builder.append(temp);
}
}
return builder.toString();
}
public static String resolveMap(String src) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < src.length(); i++) {
char temp = src.charAt(i);
if (temp >= 'B' && temp <= 'H') {
int c = temp - 'B';
temp = (char) (c + '3');
builder.append(temp);
} else if (temp == 'K') {
builder.append('Q');
} else if (temp == 'L') {
builder.append('K');
} else if (temp == 'M') {
builder.append('A');
} else if (temp == 'N') {
builder.append('2');
} else if (temp == 'I' || temp == 'J'){
builder.append(temp);
}
}
return builder.toString();
}
}