898 C. Phone Numbers

传送门

[http://codeforces.com/contest/898/problem/C]

题意

题意比较难理解直接看样例就知道了,给你个n接下来n行,每行包括一个名字和号码的数量,还有具体的每个号码
让你整理他的电话本,使得一个人的号码不能有重复,而且一个号码不能是另一个号码的后缀

分析

首先可以对一个人的所有号码去重,用map<string,set<string>> m来存信息可以,set具有惟一性,然后输出m.size()即为所有联系人
然后用三重循环来处理使得一个人的号码不能有重复,而且一个号码不能是另一个号码的后缀,关键是判断一个字符串是否是另一个字符串的
后缀,substr()函数
1. 用途:一种构造string的方法

2. 形式:s.substr(pos, n)

3. 解释:返回一个string,包含s中从pos开始的n个字符的拷贝(pos的默认值是0,n的默认值是s.size() - pos,即不加参数会默认拷贝整个s)

4. 补充:若pos的值超过了string的大小,则substr函数会抛出一个out_of_range异常;若pos+n的值超过了string的大小,则substr会调整n的值,只拷贝到string的末尾

例如:

#include<string>
#include<iostream>
using namespace std;
int main()
{
  string s("12345asdf");
  string a = s.substr(0,5);     //获得字符串s中从第0位开始的长度为5的字符串
  cout << a << endl;
}
输出结果为:12345

本题代码

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	//freopen("in.txt","r",stdin);
	while(cin>>n){
		map<string,set<string> > m;
		int num;
		string name;
		for(int i=0;i<n;i++){
			cin>>name>>num;
			string s;
			for(int j=0;j<num;j++){
				cin>>s;
				m[name].insert(s);
			}
		}
		cout<<m.size()<<endl;
		for(map<string,set<string> >::iterator it=m.begin();it!=m.end();it++){
			string name=(*it).first;
			vector<string> v;
			for(set<string>::iterator at=m[name].begin();at!=m[name].end();at++){
				string a=*at;
				bool flag=1;
				for(set<string>::iterator bt=m[name].begin();bt!=m[name].end();bt++){
					string b=*bt;
					if(a==b||a.length()>b.length()) continue;
					if(b.substr(b.length()-a.length(),a.length())==a)
					{
						flag=0; break;
					}
				}
				if(flag) v.push_back(a);
			}
			cout<<name<<' '<<v.size()<<' ';
			for(int i=0;i<v.size();i++)
			cout<<v[i]<<' ';
			cout<<endl;
		}
	}
	return 0;
}
posted @ 2018-08-18 15:11  ChunhaoMo  阅读(232)  评论(0)    收藏  举报