题意:
已知有3*m+1张牌,这些牌分为4类,
(1)‘万’,从1-m
(2)‘条’,从1-m
(3)‘桶’,从1-m
(4)白板
从3*m+1张牌中抽取n张牌,
如果牌是幸运的,它一定在序列的最左边。
不幸运的牌按照以下的排序方式:
(1)万>条>桶
(2)等级高的牌排在左边
(3)对白板的处理,白板可以视为不幸运牌中的幸运牌,它可以视为替代幸运牌,但是不具有幸运的性质。
eg:
C2 W C4,幸运牌在C2~C4的区间内,所以W的取值是C3。
依次给出n张牌,求出幸运牌的可能性有几种。
思路:
(1)只有1张牌,答案为3*m(如果这张牌是白板,就从不是白板的3*m个中选择,结果为3*m;
如果不是白板,这张牌是幸运的,随意从剩余的3*m-1张不是白板的牌中任取一张都有可能是幸运牌)。
(2)第一张的点数大于第二张,说明第一张一定是幸运的,结果是1
(3)不存在白板,就是3*m-(n-1)(3*m表示非白板的数量,n-1表示非幸运的数量)。
(4)存在白板,根据白板的位置确定可能性
如果是白板在1位置,结果就是后一个的编号
如果白板在2位置,就是白板后一个的编号-白板前一个的编号
如果白板在其他位置,就是白板后一个位置-白板前一个的编号-1.
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 1e5+10;
typedef long long LL;
LL vis[maxn];
int main(void){
LL n,m,i,j,T;
char ss[5];
scanf("%lld",&T);
while(T--){
memset(vis,0,sizeof(vis));
scanf("%lld%lld",&n,&m);
int fg = 0;
vis[n+1] = 3*m+1;
for(i=1;i<=n;i++){
scanf("%s",ss);
if(ss[0]=='W'){
fg = i;
continue;
}
LL x;
scanf("%lld",&x);
if(ss[0]=='C') vis[i] = x;
else if(ss[0]=='B') vis[i] = m+x;
else if(ss[0]=='D') vis[i] = m*2+x;
}
if(n==1) printf("%lld\n",3*m);
else if(vis[1]>vis[2]&&fg!=2) printf("1\n");
else if(fg==0) printf("%lld\n",3*m-n+1);
else{
if(fg==1) printf("%lld\n",vis[2]);
else if(fg==2) printf("%lld\n",vis[3]-vis[1]);
else printf("%lld\n",vis[fg+1]-vis[fg-1]-1);
}
}
return 0;
}