Mahjong Sorting
Time Limit: 1 Second Memory Limit: 65536 KB
DreamGrid has just found a set of Mahjong with suited tiles and a White Dragon tile in his pocket. Each suited tile has a suit (Character, Bamboo or Dot) and a rank (ranging from 1 to ), and there is exactly one tile of each rank and suit combination.
Character tiles whose rank ranges from 1 to 9
Bamboo tiles whose rank ranges from 1 to 9
Dot tiles whose rank ranges from 1 to 9
White Dragon tile
As DreamGrid is bored, he decides to play with these tiles. He first selects one of the suited tiles as the "lucky tile", then he picks tiles from the set of tiles and sorts these tiles with the following rules:
The "lucky tile", if contained in the tiles, must be placed in the leftmost position.
For two tiles and such that neither of them is the "lucky tile", if
then must be placed to the left of .
is a Character tile and is a Bamboo tile, or
is a Character tile and is a Dot tile, or
is a Bamboo tile and is a Dot tile, or
and have the same suit and the rank of is smaller than the rank of ,
White Dragon tile is a special tile. If it's contained in the tiles, it's considered as the original (not-lucky) version of the lucky tile during the sorting. For example, consider the following sorted tiles, where "3 Character" is selected as the lucky tile. White Dragon tile, in this case, is considered to be the original not-lucky version of "3 Character" and should be placed between "2 Character" and "4 Character".
As DreamGrid is quite forgetful, he immediately forgets what the lucky tile is after the sorting! Given sorted tiles, please tell DreamGrid the number of possible lucky tiles.
Input
There are multiple test cases. The first line of the input contains an integer , indicating the number of test cases. For each test case:
The first line contains two integers and (, ), indicating the number of sorted tiles and the maximum rank of suited tiles.
For the next lines, the -th line describes the -th sorted tile counting from left to right. The line begins with a capital letter (), indicating the suit of the -th tile:
If , then an integer () follows, indicating that it's a Character tile with rank ;
If , then an integer () follows, indicating that it's a Bamboo tile with rank ;
If , then an integer () follows, indicating that it's a Dot tile with rank ;
If , then it's a White Drangon tile.
It's guaranteed that there exists at least one possible lucky tile, and the sum of in all test cases doesn't exceed .
Output
For each test case output one line containing one integer, indicating the number of possible lucky tiles.
Sample Input
4 3 9 C 2 W C 4 6 9 C 2 C 7 W B 3 B 4 D 2 3 100 C 2 W C 9 3 9 C 1 B 2 D 3
Sample Output
2 4 7 25
Hint
For the first sample, "2 Character" and "3 Character" are possible lucky tiles.
For the second sample, "8 Character", "9 Character", "1 Bamboo" and "2 Bamboo" are possible lucky tiles.
题目链接: https://vjudge.net/contest/287668#problem/K
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4034
题意:
定义一副麻将牌,规则如下:有3m+1张牌,m张“万”,m张“条”,m张“筒”和1张白板
在3m+1张牌中选n张牌,但在选之前先在3m张牌(除白板外)里挑选一张牌规定它为“幸运牌”
(先理解了这句话再继续往下看)
如果n张牌里包含这张“幸运牌”,那么这张“幸运牌”一定是在最左边的位置(第一张);
如果n张牌里包含白板,那么这张白板相当于“不幸运”版本的“幸运牌”,(也就是只是和“幸运牌”的点数和种类一样,没有"幸运"这个性质。)比如题中给的例子,“三万”作为”幸运牌“,白板就是“不幸版本”的“三万”,所以放在“二万”和“四万”中间。
然后是排序规则:这么多相当于是说相同种类的牌一定是点数小的在点数大的牌的左边,种类从左到右依次是“万”“条”“筒”,也就是给出的n张牌是“一万”“两万”...“九万”“一条”“两条”...“九条”“一筒”“两筒”...“九筒”这个顺序。
最后给出你已经挑选排好序的n张牌,问你可能的“幸运牌”数量是多少。(不是只有9种牌)
题解:
这里可以不用按牌的花色划分,因为每种花色数量是一定的,只会有m个,且每个出现一次,所以后面的花色可以直接数量+m,这样就把二维的花色种类转为一维的,比如当m为9时,1万点数为1,9万为9,1条就是1万+m即为10点。
先把给出的3m+1张牌都编上号便于判断与处理。
把所有情况列出来总的有以下几种:
1.当只有1张牌时,不管这一张牌是3m里的牌还是白板,都可以当作幸运牌,结果为3m;
2.当n>=1张牌时:
①当n>=2时当第一张牌比第二张牌的点数大并且第二张不是白板时,结果为1(第1张牌是幸运牌)
②当n张牌里没有白板时,结果为3*m-(n-1)(这里的1表示第一张牌,也就是n张牌里的第1张牌可以做幸运牌,剩下n-1张牌都不能做幸运牌,还有n张牌外的所有牌(除白板))
③当有白板时:
Ⅰ当白板是第一张牌时,结果为第二张牌的点数
Ⅱ当白板是第二张牌时,结果为第三张牌的点数-第一张牌的点数
Ⅲ当白板在其余位置时,结果为白板后第一张牌的点数-白班前一张牌的点数-1
(Ⅳ当白板在最后一位时,因为开始时处理了3m+1张牌的编号,所以如果白板在最后一位可以直接用Ⅲ来算)
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5+5;
ll t,n,m,ans,temp,sum,k;
ll a[100005];
char ch;
int main() {
cin>>t;
while(t--) {
cin>>n>>m;
int p = -1;
a[n] = 3*m+1;
for(int i = 0; i <n ; i++) {
getchar();
scanf("%c",&ch);
if(ch == 'W') {
p = i;
continue;
}scanf("%d",&k);
if(ch == 'C')
a[i] = k;
else if(ch == 'B')
a[i] = m+k;
else
a[i] = 2*m+k;
// switch(ch) {
// case 'W': {
// p = i;
// break;
// }
// case 'C': {
// a[i]=k;
// break;
// }
// case 'B': {
// a[i]=m+k;
// break;
// }
// case 'D': {
// a[i] = 2*m+k;
// break;
// }
// }
}
if(n==1) {
printf("%d\n",3*m);
} else if(a[0]>a[1]&&p!=1) {
puts("1");
} else if(p==-1) {
printf("%d\n",3*m-n+1);
} else {
if(p==0) {
printf("%d\n",a[1]);
} else if(p==1) {
printf("%d\n",a[2]-a[0]);
} else {
printf("%d\n",a[p+1]-a[p-1]-1);
}
}
}
}