麻將胡牌的演算法
清一色是麻將的種類之一,指有一種花色的序數牌組成的胡牌。
數字1-9,每個數字最多4張牌;
我們不考慮具體的花色,我們只看數字;
刻字:三張一樣的牌:111.222.333
順子:三張連續的牌123,46,789
對子:兩張連續的牌;11,22,33,44
需要一個程式實現,判定給定牌,是否可以和牌;
胡牌要求:麻將 牌張數只能是2,5,8,11,14
給定牌可以組合成,除1個對子以外的其他都是刻字或者順子
胡牌輸出YES否則NO
#include<stdio.h>
#include<iostream>using namespace std;
bool Group3Same(char *p, int n)
{
char * q;
int sp = 0;
int i, j;
q = p;
if (n == 0)
{
return true;
}
for (i = 0; i < n - 2; i++)
{
if (*(q + i + 1) == *(q + i) && *(q + i + 2) == *(q + i + 1))
{
if (i == n - 3) //把這三個元素移除,把後面的元素往前移動三格
{
*(q + i) = '\0';
p = q;
return true;
}
else
{
for (j = i; j < n - 3; j++)
{
*(q + j) = *(q + j + 3);
}
*(q + j) = '\0';
p = q;
return true;
}
}
}
return false;
}
int Group3Shunzi(char *p, int n)
{
char *q, *w;
int i, j, k, m, l, sp = 0;
m = 0;
q = p;
w = p;
if (n == 0)
{
return 0;
} for (i = 0; i < n - 2; i++)
{
for (j = i + 1; j < n - 1; j++)
{
if (*(q + j) - *(q + i) == 1)
{
for (k = j + 1; k < n; k++)
{
if (*(q + k) - *(q + j) == 1)
{
if (i == n - 3) //把這三個元素移除,把後面的元素往前移動三格
{
*(q + i) = '\0';
n -= 3;
i--;
break;
}
else
{
*(q + i) = '0';
*(q + j) = '0';
*(q + k) = '0';
for (m = 0, l = 0; l < n; l++)
{
if (*(q + l) != '0')
{
*(w + (m++)) = *(q + l);
}
}
n = m;
q = w;
i--;
break;
}
}
}
}
continue;
}
}
return n;
}
bool Group3S(char *p, int n)
{
char pp[14], p2[14];
int i, j;
for (i = 0; i < n; i++)
{
pp[i] = *(p + i);
p2[i] = *(p + i);
}
bool flag = false;
if (n == 0)
{
return true;
}
if (!Group3Shunzi(p, n))
return true;
if (Group3Same(p2, n)) //順子出錯,就看看有沒有三個相同的,有就把三個相同的挑出來,在進行順子演算法
{
n -= 3;
flag = Group3S(p2, n);
}
return flag;
}
bool Group(char *pp, int n)
{
char q[14];
char r;
int i, j, k = 0;
r = '0';
for (i = 0; i < n; i++)
{
q[i] = *(pp + i);
}
if (n == 0)
{
return true;
}
else if (n % 3 == 2) //必定存在一對對子
{
for (i = k; i<n - 1; i++)
{
if (*(q + i) == *(q + i + 1) && *(q + i) != r) //找對子,並剔除對子
{
r = *(q + i);
for (j = i; j < n - 2; j++)
{
*(q + j) = *(q + j + 2); //所有元素左移兩位
}
*(q + j) = '\0';
i--;
k = i;
if (Group3S(q, n - 2)) //某一花色組合正確
{
return true;
}
for (j = 0; j < n; j++)
{
q[j] = *(pp + j); //恢復原來的陣列,並進行下一輪對子的選擇
}
} //找出對子,並剔除,在剩餘的12張牌中進行組合
}
}
else //沒有對子,只能是三個三個一組(三個相同或者順子)
{
if (Group3S(q, n))
{
return true; //某一花色組合正確
}
}
return false; //輸了
}
void main()
{
/*char s[11] ,*p;
p = s;
gets(p);
int n;
n = *p - '0';
while (*++p)
{
n = n * 7 + *p - '0';
}
printf("%d",n);*/
char *as1 = "11";
char *as2 = "111222336";
char *as3 = "11122233369";
int d=Group(as3, 11);
if (d == 1)printf("%s", "yes");
else printf("%s","no");
cin.get();
}