ggwdwsbs最近被Zeratul和Kyurem拉入了日本麻将的坑。现在,ggwdwsbs有13张牌,Kyurem又打了一张,加起来有14张牌。ggwdwsbs想拜托你帮他判断一下,这14张牌能否和。
为了方便起见,本题不考虑字牌,即只有万,筒,条三种类型的牌,牌上带有数字1~9,相同的牌最多可能出现四次。
麻将想要和,必须把14张牌凑成指定的类型——七对子(2222222的形式)或四面子一雀头(23333的形式)。
其中,七对子是指14张牌恰好是7对相同的牌(每两对牌不得相同),如果凑出这样的牌,就可以直接和了;
四面子一雀头是指有一对相同的牌,且其他12张牌凑出四个“3”,这里的“3”可以是三个一样的牌(即刻子),也可以是数字连续且种类一样的三张牌(即顺子)。
在日本麻将中,把牌凑成第二种类型(“23333”)是不足以和牌的,还需要满足另一个条件——存在役。
下面介绍本题要求考虑的四种役。
1. 断幺九:14张牌里没有带数字1和数字9的牌出现。
2. 纯全带幺九:与第一种相反,这种类型要求,那一对相同牌和四个“3”中都要出现至少一张带数字1或9的牌。
3. 平和:四个“3”全部以顺子的形式出现。
4. 对对和:四个“3”全部以刻子的形式出现
满足上述四种中的一种,且满足“23333”的格式,也可以和牌。
请帮ggwdwsbs判断一下,他这14张牌能否和。
输入
第一行一个整数t,表示测试数据组数.
第二行到第t+1,每行有14个范围在1到27之间的整数,每个整数代表一张牌编号。
其中,编号1~9表示“万”的1~9,编号10~18表示“筒”的1~9,编号19~27表示“条”的1~9。
数据保证t≤100,每行的14张牌按编号从小到大给出。
输出
输出t行,每行一个整数,如果能和请输出1,不能和请输出0。
注:日麻的规则还有有很多本题所没有提及,如果你是一个日麻高手,请假装自己不知道那些规则以AC本题。
输出时每行末尾的多余空格,不影响答案正确性
样例输入
6 1 1 2 2 3 3 4 4 5 5 6 6 7 7 1 2 3 4 5 6 7 8 9 10 10 10 13 13 1 1 1 2 2 2 3 3 3 4 4 4 5 5 1 1 1 2 3 4 5 6 7 8 9 10 11 12 1 1 1 1 2 3 10 11 12 19 20 21 27 27 2 2 2 3 4 5 6 7 8 11 11 11 12 13
样例输出
1 0 1 1 1 1
题目来源
很坑的一道题,代码很长,写了一下午终于过了。
思路:
①先把将选出来,‘将’就是23333中的2,我们那打麻将叫‘将’。由于有多种情况,所以要对出现次数大于2的牌都当做将考虑一下。这是第一步
②剩下的牌从第一个到最后一个进行判断,用一个循环遍历3333,分别讨论出现次数为1,2,3,4的情况。这个循环的目的是判断他能不能听牌(3333中是否是顺子或 刻子)。
对于出现次数为1的牌,必定是顺子,往后找两张牌,插到顺子的vector里面
对于出现次数为2的牌,也是顺子,因为将已经选出来了,同样,往后找,插到vector里面
对于出现次数为3的牌,有可能是顺子,也有可能是刻子,所以又要判断,这里我出来的方法是,创建versatile1,versatile2两个vector,分别表示可变化的顺子和刻子,最后再进行判断
对于出现次数为4的牌,同上讨论。
③虽然3333能够构成顺子或刻子,但是还要考虑 1 9,还要考虑是否全部是顺子,或者全部是刻子。
④对于七对 的判断,写在所以判断的前面,即一旦输入就判断。
主要看思路吧,代码写的太乱,也不想去简化,这次比赛体验感非常差,连个签到题都没得
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <deque>
#include <set>
#include <map>
using namespace std;
#define inf 0x7f7f7f7f
typedef long long ll;
vector<int> v; //原本的
int num[30];
int change( int t )
{
return (t-1)%9+1;
}
int f( int t )
{
int temp = change(t);
if( temp == 1 || temp == 9 )
return true;
return false;
}
bool judge_qidui()
{
for( int i = 1 ; i <= 27 ; i++ )
{
if( num[i] == 1 || num[i] > 2 )
return false;
}
return true;
}
bool solve( vector<int> vec,int time[],int jiang )
{
vector<int> shunzi;
vector<int> three;
vector<int> versatile1; //万能 顺子
vector<int> versatile2; //万能 three
shunzi.clear();
three.clear();
versatile1.clear();
versatile2.clear();
sort( vec.begin(),vec.end() );
for( int i = 0 ; i < vec.size() ; i++ )
{
int t = vec[i];
if( time[t] == 0 )
continue;
if( time[ t ] == 1 )
{
if( change(t) > 7 )
return false;
if( time[t+2] < 1 || time[t+1] < 1 )
return false;
else
{
time[t]--;
time[t+1]--;
time[t+2]--;
shunzi.push_back(t);
shunzi.push_back(t+1);
shunzi.push_back(t+2);
}
}
else if( time[ t ] == 2 )
{
if( change(t) > 7 )
return false;
if( time[t+2] < 2 || time[t+1] < 2 )
return false;
else
{
time[t] = 0;
time[t+1] -= 2;
time[t+2] -= 2;
shunzi.push_back(t);
shunzi.push_back(t+1);
shunzi.push_back(t+2);
shunzi.push_back(t);
shunzi.push_back(t+1);
shunzi.push_back(t+2);
}
}
else if( time[ t ] == 3 )
{
if( change(t) > 7 || time[t+1]<3 || time[t+2]<3 )
{
three.push_back(t);
time[t] = 0;
}
else if( time[t+1]>= 3 && time[t+2]>= 3 ) // 3 3 3 或者 3 3 4
{
time[t] = 0;
time[t+1] -= 3;
time[t+2] -= 3;
for( int j = 1 ; j <= 3 ; j++ )
{
versatile1.push_back(t);
versatile1.push_back(t+1);
versatile1.push_back(t+2);
}
versatile2.push_back(t);
versatile2.push_back(t+1);
versatile2.push_back(t+2);
}
}
else if( time[t] == 4 )
{
if( change(t) > 7 || time[t+1] == 0 || time[t+2] == 0 )
return false;
if( time[t+1] == 4 && time[t+2] == 4 )
{
time[t] = time[t+1] = time[t+2] = 0;
for( int j = 1 ; j <= 4; j++ )
{
shunzi.push_back(t);
shunzi.push_back(t+1);
shunzi.push_back(t+2);
}
}
else // 4 1 1
{
time[t] = 0;
time[t+1]--;
time[t+2]--;
shunzi.push_back(t);
shunzi.push_back(t+1);
shunzi.push_back(t+2);
three.push_back(t);
}
}
}
if( shunzi.size()+versatile1.size() == 12 )
return true;
if( three.size()+versatile2.size() == 4 )
return true;
bool type1 = false,type2 = false; //type1 是全部 1 9
for( int i = 0 ; i < shunzi.size() ; i+= 3 )
{
if( f( shunzi[i] ) || f( shunzi[i+1] )|| f( shunzi[i+2] ) )
type1 = true;
else type2 = true;
}
for( int i = 0 ; i < versatile1.size() ; i+=3 )
if( f( versatile1[i] ) || f( versatile1[i+1] )|| f( versatile1[i+2] ) )
type1 = true;
else type2 = true;
for( int i = 0 ; i < three.size() ; i++ )
if( f( three[i] ) )
type1 = true;
else type2 = true;
if( type1 == true && type2 == true )
return false;
if( type1 == true && f(jiang) == false )
return false;
if( type2 == true && f(jiang) )
return false;
//cout<<"here";
return true;
}
int main()
{
int T;
scanf("%d",&T);
while( T-- )
{
int item;
memset(num,0,sizeof num);
v.clear();
bool toomuch = false;
for( int i = 1 ; i <= 14 ; i++ )
{
scanf("%d",&item);
v.push_back(item);
num[item]++;
if( num[item] > 4 )
{
toomuch = true;
break;
}
}
if( toomuch == false )
{
bool ans = false;
if( judge_qidui() )
ans = true;
else
{
vector<int> temp;
int t[30];
for( int i = 0 ; i < v.size() ; i++ )
{
if( num[ v[i] ] >= 2 )
{
int cnt = 0;
temp.clear();
memset(t,0,sizeof t);
for( int j = 0 ; j < v.size() ; j++ )
{
if( v[j] != v[i] )
{
t[ v[j] ]++;
temp.push_back(v[j]);
}
else if( v[j] == v[i] )
{
if( 2+cnt<num[ v[i] ] )
{
temp.push_back(v[i]);
t[ v[j] ]++;
cnt++;
}
}
}
if( solve(temp,t,v[i]) ) //选出 将 ,然后判断
{
ans = true;
break;
}
}
}
}
if( ans )
puts("1");
else puts("0");
}
else
{
puts("0");
}
}
return 0;
}
/*
100
6
1 6 8 9 9 8
*/