算法比较简单,郁闷的是卡在输出格式上,多了一个换行,在输出时一定要和题目的输出一直,看清题目的要求。
出现这些问题的本质,还是编程思路不够严谨,要着重锻炼自己思维的严谨性、写代码时的专注度。对于分支部分的代码考虑清楚再敲,复制、排序在重复用到的数组中考虑覆盖、初始化的问题。
本题是一个简单的搜索。有一点,对按牌大小排过序的数组求顺子,以当前牌为顺子的起始,从左到右匹配顺子,如果未匹配上,则当前排不存在顺子。因为在排序数组中,若果搜索到当前下标,则说明之前的一小于当前下标的牌开始的顺子都匹配失败,也就是说当前下标牌在顺子中排在第2-n个位置的情况都匹配失败,所以若果当前下标匹配失败则当前排肯定无顺子。
对字符串输入的,开一个str数组,匹配下标,转换成整数操作。方便!
思路:从34张牌中取一张加入,看是否胡牌,胡牌则输出。
先选将,搜索顺子和刻子的排列组合,每次搜索到第3层(0开始)时则成功,3*4 +2 == 14;
每一张牌匹配刻子、和以它开头的顺子,匹配成功则返回1,否则返回0;
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
using namespace std;
const char* mj[] = {
"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"};
int us[34];//1- 9s 1*9+1 - 2*9t, 3*9+1 - 4*9,
int hand[14],kase = 1;
int check(int dep)
{
for(int i = 0; i < 14; i++)
{
if(!us[hand[i]])continue;
if(us[hand[i]] >= 3)//找当前牌的 刻子
{
//printf("%d\n",dep);
if(dep == 3)return 1;
us[hand[i]] -= 3;
int r = check(dep + 1);
us[hand[i]] +=3;
if(r)return 1;
}
// 找当前牌的 顺子
if((
(hand[i] >= 0 && hand[i] < 9 - 2) ||
(hand[i] >=9 && hand[i] < 18 - 2)||
(hand[i] >=18 && hand[i] < 27 - 2)
) &&
us[hand[i] + 1] > 0 && us[hand[i] + 2] >0)//箭牌 和风牌 没有 顺子
{
if(dep == 3)return 1;
us[hand[i]]--;
us[hand[i] + 1]--;
us[hand[i] + 2]--;
int result = check(dep+1);
us[hand[i]]++;
us[hand[i] + 1]++;
us[hand[i] + 2]++;
return result;
}
return 0;
}
}
void find()
{
int is_ting = 0;
int tmp[13];
for(int i = 0; i < 13; i++)tmp[i] = hand[i];
for(int i = 0; i < 34; i++)
{
if(us[i] == 4)continue;
hand[13] = i;
us[i]++;
sort(hand,hand + 14);
for(int j = 0; j < 14; j += us[hand[j]])
{
if(us[hand[j]] >= 2)
{
us[hand[j]] -= 2;
if(check(0))
{
printf(" %s",mj[i]);
is_ting = 1;
us[hand[j]] += 2;
break;
}
us[hand[j]] += 2;
}
}
us[i] --;
for(int k = 0; k < 13; k++)hand[k] = tmp[k];
}
if(!is_ting)printf(" Not ready");
printf("\n");
}
int getId(const char* c)
{
for(int i = 0; i < 34; i++)
if(!strcmp(c,mj[i]))return i;
}
int main(int argc, char *argv[])
{
char str[5];
while(1)
{
memset(us,0,sizeof(us));
scanf("%s",str);
if(str[0] == '0')break;
hand[0] = getId(str);
us[hand[0]]++;
for(int i = 1; i < 13; i++)
{
scanf("%s",str);
hand[i] = getId(str);
us[hand[i]]++;
}
printf("Case %d:",kase++);
find();
}
//system("PAUSE");
return EXIT_SUCCESS;
}