列表

详情


NC220392. Riichi!!

描述

Yui is a cute girl expert in a kind of  game. In case you are not familiar with the game, here we briefly introduce its rules.

 is played with , divided into 34 . To simplify the problem, we assume that  (although in real-world game one kind usually contains up to 4 tiles). The 34 kinds of tiles can be further divided into 4 , named as , and . The  have 9 kinds for each suite and  tiles has only 7 kinds.

Here are the all 34 kinds of tiles used in  game: Each row refers to a suite of tiles ---  in order.






Minor differences exist in various versions of  game, and here we only consider some basic rules.

During the game, each player holds 13 tiles in hand. For each round, one player would draw one tile from the Mahjong table, then discard one tile from one of the 14 tiles owned at the time. A player wins the game if in a round he can create a  (defined below) with the 13 tiles in hand and 1 tiles drawn from table or discarded from other player.

 consists of 14 tiles, which can be divided into four \texttt{kezi} or , and an additional .

Here,  is a set of 3 identical tiles:





And  is a set of 3 continuous tiles (please aware that suite \texttt{zi} cannot form ) :



Finally,  is a pair of identical tiles:




Here are some samples of special combinations:




The second example might be confusing. Since you can combine your tiles arbitrary, the actual combination is the follows:


If the player can obtain a special combination by getting some tile, then we call the player is in the  status. In this status one can achieve victory once he/she gets the desired kind of tile!

For example, the following sets of 13 tiles are in the  status, the tiles after the space indicates the desired tiles to achieve victory.





Now Yui is playing the  game. Sometimes she is very close to victory that if she tosses some tile she would reach the  status, while sometimes such tiles does not yet exist. And sometimes she has already got a winning hand of 14 tiles!

To help you improve your  skills, Yui decides to give you a test. Now it is Yui's turn and she has 14 tiles in her hand. Please tell her which tile should be discarded in order to reach  status, or just tell her that she has already won in this round!

输入描述

The input contains multiple tests cases. The first line includes a single integer  --- the number of test cases. It is guaranteed that .

Each of the next  lines indicates a test case. It contains a string  of 28 characters, describing the 14 tiles that Yui currently has. For every , the -th tile obtained by Yui is described by the -th and -th characters in the string: the former is a digit denoting the rank of the tile in its suite and the latter is one of \texttt{w, b, s, z}, which means the suite  and  respectively. It is guaranteed that all the  in the input are valid and legal.


输出描述

Output the answer for each test case separately. For each test case, if Yui has already reach the winning status in this round, output  in a single line.

Otherwise, output a single integer  in a single line, the number of choices for discarding tiles to reach  status.

Each of the next  lines should indicate one way to reach the  status. It should start with two characters indicating the tile to be discarded. To prove that such way leads to a  status, you should print all the tiles that can lead to victory for the status. For clarity, print a space between the first two characters and the rest of the line.

 Pay attention to the order when printing the desired tiles, as there is NO special judge. For tiles in different suites, print them in the order  (that is, always print  tiles at first, and so on). For tiles in the same suite, print the cards in the ascending order of their digits (that is, the tile with smaller number goes first). Additionally, if there are several tiles available for a  status to achieve victory, you should also sort them in the same way. See the Sample Output for details.


示例1

输入:

5
1w2w3w4b5b6b7s8s9s1b1b1z2z6z
1w2w3w4b5b6b7s8s9s1b1b2z2z6z
1w2w3w4b5b6b7s8s9s1b1b2z2z2z
1b2b3b4b5b6b2s4s5s5s5s6s7s8s
1b1b1b2b3b4b5b6b7b8b9b9b9b1s

输出:

0
1
6z 1b2z
Tsumo!
4
2s 3s4s6s9s
4s 2s
5s 3s
8s 3s
4
2b 1s
5b 1s
8b 1s
1s 1b2b3b4b5b6b7b8b9b

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 483ms, 内存消耗: 652K, 提交时间: 2022-10-08 21:12:58

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll=long long;

int id(char x){
	if(x=='w')return 0;
	if(x=='b')return 1;
	if(x=='s')return 2;
	return 3;
}
int a[34];
void init(){
    memset(a,0,sizeof a);
    string str;cin>>str;
    for(int i=0;i<28;i+=2){
        int x=str[i]-'0';
		++a[x-1+9*id(str[i+1])];
    }
}
int ta[34];
int check(){
	memcpy(ta,a,sizeof ta);
	for(int i=27;i<34;++i)
		if(ta[i]%3)return 0;
	for(int i=0;i<27;++i){
		ta[i]%=3;
		if(ta[i]){
			if(i%9>6)return 0;
			int mi=min(ta[i],min(ta[i+1],ta[i+2]));
			if(ta[i]>mi)return 0;
			ta[i]-=mi,ta[i+1]-=mi,ta[i+2]-=mi;
		}
	}
	return 1;
}
int win(){
	for(int i=0;i<34;++i){
		if(a[i]>=2){
			a[i]-=2;
			int f=check();
			a[i]+=2;
			if(f)return 1;
		}
	}
	return 0;
}
vector<int>ans[34];
string change(int x){
	int y=x/9;
	x%=9;
	return string(1,x+1+'0')+"wbsz"[y];
}
signed main() {
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T;cin>>T;
    while(T--){
        init();
        if(win()){
            cout<<"Tsumo!\n";
            continue;
        }
        int cnt=0;
		for(int i=0;i<34;++i){
			ans[i].clear();
			if(!a[i])continue;
			--a[i];
			for(int j=0;j<34;++j){
				if(i==j)continue;
				++a[j];
				if(win())ans[i].push_back(j);
				--a[j];
			}
			++a[i];
			if(!ans[i].empty())++cnt;
		}
		cout<<cnt<<endl;
		for(int i=0;i<34;++i){
			if(ans[i].empty())continue;
			cout<<change(i)<<' ';
			for(auto it:ans[i])cout<<change(it);
			cout<<endl;
		}
    }
	return 0;
}
// init?
// var->0?
// infinite dfs?
// out of bound?
// max_element / min_element?

C++(clang++11) 解法, 执行用时: 306ms, 内存消耗: 896K, 提交时间: 2021-04-19 11:51:22

#include<vector>
#include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std;

int T,a[34];
char s[23];

bool he2(int b[]){
	rep(i,0,33) a[i]=b[i];
	rep(i,0,26) if (a[i]%3){
		if (i%9>6) return 0;
		a[i]=a[i]%3;
		if (a[i]>a[i+1]||a[i]>a[i+2]) return 0;
		a[i+1]-=a[i]; a[i+2]-=a[i]; a[i]=0;
	}
	rep(i,27,33) if(a[i]%3) return 0;
	return 1;
}

bool he(int b[]){
	int a[34];
	rep(i,0,33) a[i]=b[i];
	rep(i,0,33) if(a[i]>=2){
		a[i]-=2;
		if (he2(a)) return 1;
		a[i]+=2;
	}
	return 0;
}

char gett(int x){
	if(x==0) return 'w';
		else if(x==1) return 'b';
			else if(x==2) return 's';
				else return 'z';
}

int main(){
	for (scanf("%d",&T); T--; ){
		scanf("%s",s);
		int cnt=0,x[37]={0};
		vector<int> ans[37];
		rep(i,0,13){
			if(s[i*2+1]=='w') x[s[i*2]-'1']++;
				else if(s[i*2+1]=='b') x[s[i*2]-'1'+9]++;
					else if(s[i*2+1]=='s') x[s[i*2]-'1'+18]++;
						else x[s[i*2]-'1'+27]++;
		}
		if(he(x)) printf("Tsumo!\n");
		else{
			rep(i,0,33) if(x[i]){
				rep(j,0,33){
					x[i]--; x[j]++;
					if(he(x)) ans[i].push_back(j);
					x[j]--; x[i]++;
				}
				if(ans[i].size()) cnt++;
			}
			printf("%d\n",cnt);
			rep(i,0,33) if(ans[i].size()){
				printf("%d%c ",i%9+1,gett(i/9));
				for (int j=0; (int)j<ans[i].size(); j++)
					printf("%d%c",ans[i][j]%9+1,gett(ans[i][j]/9));
				puts("");
			}
		}
	}
	return 0;
}

上一题