1 条题解
-
0
这个问题需要我们高效地存储多个规范排序的牌组链表,通过共享公共尾节点来减少内存使用。核心思路是利用字典树(Trie)的结构特性来实现节点共享。
核心数据结构与设计思路
-
字典树(Trie):
- 使用二维数组表示字典树,其中
a[e][q]
表示节点的子节点 - 每个节点代表一张牌,路径表示牌组
- 使用二维数组表示字典树,其中
-
牌的编码:
- 将每张牌编码为之间的唯一整数
- 点数映射为,花色分别映射为
- 最终编码为
-
逆向插入:
- 由于需要共享尾节点,每次插入牌组时逆序处理牌,使得字典树的深度方向对应链表的尾部到头部
核心算法解析
-
字典树构建:
- 初始化根节点为
- 对于每个牌组,逆序处理每张牌,插入到字典树中
- 如果节点不存在,则创建新节点,否则复用现有节点
-
节点计数:
- 字典树中的节点总数即为所需链表节点数
- 由于根节点不代表实际牌,最终结果为总节点数减
代码实现
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> int ans=0,p,n; int a[100000][100]; char s[400000]; int q[300000],c[100000],w[100000],g[100000]; void lily(){//字典树建树 int e=1; for(int i=0;i<n;i++){ if(a[e][q[i]]==0) a[e][q[i]]=++p; e=a[e][q[i]]; } } int main(void){ int i,j,k,m,t; for(i=2;i<=9;i++) w[i+'0']=i-1; w['A']=0;w['J']=10;w['Q']=11;w['K']=12; g['c']=0;g['D']=13;g['H']=26;g['S']=39; while(scanf("%d",&t)==1&&t){ memset(a,0,sizeof(a));//清空 p=1; while(t--){ scanf("%d",&n); for(i=0;i<n;i++){ scanf("%s",s); if(s[0]=='1'&&s[1]=='0')//统计 q[n-i-1]=9+g[s[2]]; else q[n-i-1]=w[s[0]]+g[s[1]]; } lily(); for(i=0;i<n;i++)q[i]=0;//清空 } printf("%d\n",p-1);//输出 } return 0; }
复杂度分析
- 时间复杂度:O(N),其中N为所有牌组中的牌总数
- 空间复杂度:O(N),主要用于存储字典树
注意事项
-
输入处理:
- 正确处理牌的编码,特别是10的特殊情况
- 逆序处理牌组以共享尾节点
-
内存管理:
- 使用二维数组表示字典树,适用于节点数不超过100,000的情况
- 每次测试用例后需要重置字典树
-
结果输出:
- 节点数需排除根节点,因此结果为总节点数减1
-
- 1
信息
- ID
- 2284
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者