NC51245. 扑克牌
描述
输入描述
第一行为一个整数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; }