列表

详情


NC51245. 扑克牌

描述

一副不含王的扑克牌由52张牌组成,由红桃、黑桃、梅花、方块4组牌组成,每组13张不同的面值。现在给定52 张牌中的若干张,请计算将它们排成一列,相邻的牌面值不同的方案数。 牌的表示方法为XY,其中X为面值,为2、3、4、5、6、7、8、9、T、J、Q、K、A中的一个。Y为花色,为S、 H、D、C中的一个。如2S、2H、TD等。 

输入描述

第一行为一个整数T,为数据组数。
之后每组数据占一行。这一行首先包含一个整数N,表示给定的牌的张数,
接下来N个由空格分隔的字符串,每个 字符串长度为2,表示一张牌。每组数据中的扑克牌各不相同。

输出描述

对于每组数据输出一行,形如"Case #X: Y"。X为数据组数,从1开始。Y为可能的方案数,由于答案可能很大, 请输出模 之后的值。

示例1

输入:

5
1 TC
2 TC TS
5 2C AD AC JC JH
4 AC KC QC JC
6 AC AD AS JC JD KD

输出:

Case #1: 1
Case #2: 0
Case #3: 48
Case #4: 24
Case #5: 120

原站题解

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

C++ 解法, 执行用时: 35ms, 内存消耗: 2396K, 提交时间: 2021-11-06 09:27:22

#include<bits/stdc++.h>

using namespace std;
typedef unsigned long long ull;
//const ull mod=(1>>61);
const int N=14;
ull dp[N][N][N][N][5];
char s[5];
int cnt[N],a[5];
ull dfs(int a,int b,int c,int d,int p){
	
	if(dp[a][b][c][d][p]!=-1){
		return dp[a][b][c][d][p];
	}
	ull ans=0;
	if(a){
		ans+=dfs(a-1,b,c,d,1)*1*(a-(p==2));
	}
	if(b){
		ans+=dfs(a+1,b-1,c,d,2)*2*(b-(p==3));
	}
	if(c){
		ans+=dfs(a,b+1,c-1,d,3)*3*(c-(p==4));
	}
	if(d){
		ans+=dfs(a,b,c+1,d-1,4)*4*d;
	}
	dp[a][b][c][d][p]=ans;
	return ans;
}
int main(){
	int T,n;
	memset(dp,-1,sizeof(dp));
	for(int i=0;i<=4;i++){
		dp[0][0][0][0][i]=1;
	}
	scanf("%d",&T);
	for(int t=1;t<=T;t++){
		scanf("%d",&n);
		
		memset(cnt,0,sizeof(cnt));
		memset(a,0,sizeof(a));
		for(int i=1;i<=n;i++){
			scanf("%s",s);
			if(s[0]>='2' && s[0]<='9'){
				cnt[s[0]-'0']++;
			}else if(s[0]=='T'){
				cnt[10]++;
			}else if(s[0]=='J'){
				cnt[11]++;	
			}else if(s[0]=='Q'){
				cnt[12]++;
			}else if(s[0]=='K'){
				cnt[13]++;
			}else if(s[0]=='A'){
				cnt[1]++;
			}
		}
		for(int i=1;i<=13;i++){
			a[cnt[i]]++;
		}
		
		ull ans=dfs(a[1],a[2],a[3],a[4],0);
		printf("Case #%d: %llu\n",t,ans);
	}
	
	return 0;
} 

上一题