题目描述
一个电话销售员正在整理他的电话簿。
电话簿中记录了他的全部客户的电话号码。
一个客户可能有不止一个电话号码。
不同客户可能拥有完全相同的电话号码。
电话簿中一共包含 n 条记录。
每条记录都是首先包含一个字符串,表示客户的姓名,然后包含一个整数,表示本条记录包含的电话号码数量,最后是本条记录所包含的电话号码。
不同客户的姓名两两不同,所以如果两条记录包含的客户姓名相同,那么我们认为这都是记录的同一人的电话信息。
同一记录中可能包含相同的电话号码,不同记录中也可能包含相同的电话号码。
在进行整理时,应遵守如下原则:
如果一个客户拥有多条记录,则需要将这些记录进行合并,每人只保留一条记录,去记录他的全部有效号码。
如果一个客户记录的多个电话号码完全相同,则只保留一个作为有效号码,其余的全部视为无效号码。
如果一个客户记录的两个不同电话号码 a 和 b 满足 a 是 b 的后缀,则号码 a 视为无效号码。
请输出整理后的电话记录。
输入格式
第一行包含整数 n,表示记录数量。
接下来 n 行,每行描述一条记录,首先包含一个长度不超过 10 的由小写字母构成的非空字符串,表示客户姓名,然后包含一个不超过 10 的正整数,表示本条记录包含的号码数量,最后包含本条记录的所有号码,每个号码都是长度不超过 10 的由数字构成的非空字符串,可能包含前导 0。
输出格式
首先输出一个整数 m,表示完成整理后的记录数量。
接下来 m 行,每行输出一条记录信息,格式要求与输入一致。
同一行的数据之间用单个空格隔开。
记录的先后顺序随意,一条记录中的号码顺序随意。
数据范围
前三个测试点满足 1≤n≤4。
所有测试点满足 1≤n≤20。
#include<bits/stdc++.h>
using namespace std;
struct rec{
string nm;
string p[11111];
int sum;
}yh[111];
int n,cnt;
string a;
map<string,int>mp;
int m;
string num;
int main()
{
cin>>n;
for (int i = 1; i <= n; i ++ ){
cin >> a>>m;
int k=mp[a];
if(!k){
mp[a]=k=++cnt;
yh[cnt].nm=a;
}
for (int j = 1; j <= m; j ++ ){
cin>>num;
yh[k].p[++yh[k].sum]=num;
}
}
cout<<cnt<<"\n";
for(int i=1;i<=cnt;i++){
cout<<yh[i].nm<<" ";
bool bb[11111];
memset(bb,0,sizeof(bb));
for (int j = 1; j <= yh[i].sum; j ++ ){
for (int k = j+1; k <=yh[i].sum; k ++ ){
string aa=yh[i].p[j];
string b=yh[i].p[k];
int sa=aa.size();
int sb=b.size();
if(sa>sb){
string y=aa.substr(sa-sb,sb);
if(y==b){
bb[k]=1;
}
}
else {
string y=b.substr(sb-sa,sa);
if(y==aa){
bb[j]=1;
}
}
}
}
int s=0;
for (int j = 1; j <= yh[i].sum; j ++ ){
if(!bb[j])s++;
}
cout<<s<<" ";
for (int j = 1; j <= yh[i].sum; j ++ ){
if(!bb[j])cout<<yh[i].p[j]<<" ";
}
cout<<"\n";
}
}