UVA

/*
  用到的处理手法 or 收获 or 注意事项:
  1. substr函数分离邮箱的用户名和MTA,当需要有两个返回值时,通过传两个引用并改变它们来实现
  
  2.对于map,在使用map[key]前,必须先检查一下key是否存在
  如果map不包含key,使用下标有一个危险的副作用,会在map中插入一个key的元素,value取默认值,返回value。也就是说,map[key]不可能返回null
  
  见blog: http://www.cnblogs.com/nzbbody/p/3409298.html

  3.在输出时要输出很多空格,所以不妨把5个空格作为一个常量space来输出
  
  4.空格的处理一定要小心谨慎,为此PE过一次
*/

#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <map>
//#define debug
using namespace std;
const string space = "     ";  

void separate(const string &s, string &user, string &mta)
{
	int k = s.find('@');
	user = s.substr(0, k);
	mta = s.substr(k + 1);
}

int main()
{
	
	#ifdef debug
	freopen("E:\in.txt", "r", stdin);
	freopen("E:\out.txt", "w", stdout);
	#endif
	
	int k;
	string s, t, user1, mta1, user2, mta2;
	set<string> addr;

	//输入所有MTA,转换为地址列表 
	while (cin >> s && s != "*") //s为 MTA 而非 *  
	{
		cin >> s >> k;
		while (k--)
		{
			cin >> t;
			addr.insert(t + "@" + s);
		}
	}

	while (cin >> s && s != "*") //处理发件人地址 
	{
		separate(s, user1, mta1);
		
		vector<string> mta; //所有需要连接的mta,按照输入排序
		map<string, vector<string> > dest; //每个MTA需要发送的客户
		set<string> vis;
		
		while (cin >> t && t != "*")
		{
			separate(t, user2, mta2); //处理收件人地址
			if (vis.count(t)) continue; //重复的收件人
			vis.insert(t);
			if (!dest.count(mta2))
			{
				mta.push_back(mta2);
				dest[mta2] = vector<string> ();
			} 
			dest[mta2].push_back(t);
		} 
		
		getline(cin, t); //是为了吃掉 * 后的那个回车,也可用 getchar() 代替
		
		string data;
		while (getline(cin, t) && t[0] != '*') data += space + t + "
";
		
		for (int i = 0; i < mta.size(); i++)
		{
			string mta2 = mta[i];
			vector<string> users = dest[mta2];
			
			cout << "Connection between " << mta1 << " and " << mta2 << endl;
			cout << space << "HELO " << mta1 << "
"; 
			cout << space + "250
";
			cout << space + "MAIL FROM:<" + s + ">
";
			cout << space + "250
"; 
			
			bool ok = false;
			for (int j = 0; j < users.size(); j++)
			{
				cout << space + "RCPT TO:<" + users[j] << ">
";
				cout << space;
				if (addr.count(users[j]))
				{
					ok = true;
					cout << "250
";
				}
				else cout << "550
";
			}
			if (ok) cout << space + "DATA
" + space + "354
" + data + space + ".
" + space + "250
";
			cout << space + "QUIT
" + space << "221
";
		}
	}
	
	#ifdef debug
	fclose(stdin);
	fclose(stdout);
	#endif

	return 0;
}

原文地址:https://www.cnblogs.com/mofushaohua/p/7789439.html