1 条题解

  • 0
    @ 2025-5-30 11:44:35

    题意分析

    当某人从user1@mta1发送给另一个人user1@mta2时,这两个MTA将会通信。 如果两个收件人属于同一个MTA,发送者的MTA只需与这个MTA通信一次就可以把邮件发送给这两个人。 输入每个MTA里用户列表,对于每个发送请求(发送者和接收者),按顺序输出所有MTA之间的SMTP(简单邮件协议)交互。 发送人MTA连接收件人MTA的顺序应该与在输入中第一次出现的顺序一致。 例如,若发件人是Hamdy@Cairo,收件人列表为Conrado@MexicoCity、Shariff@SanFrancisco、Lisa@MexicoCity, 则Cairo应当依次连接MexicoCity和SanFrancisco。 如果连接某个MTA之后发现所有收件人都不存在,则不应该发送DATA。所有用户名均由不超过15个字母和数字组成。

    解题思路

    把每个MTA里的用户列表保存下来。可以用map<string,vector<string>>map<string, vector<string> >, 其中键是MTA名称(string类型),值是用户名列表(vector<string>vector<string>)。(map[MTA]=名字map[MTA]=名字) 一个更简单的方法是用一个set<string>set<string>,值就是{邮件地址}。 读入发件人,分离出MTA和用户名,然后读入所有收件人,根据MTA出现的顺序进行保存,并且去掉重复。 接下来读入邮件正文,最后按顺序依次连接每个MTA,检查并输出每个收件人是否存在, 如果至少有一个存在,则输出邮件正文。

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <set>
    #include <map>
    #include <vector>
    using namespace std;
    void fen(string s, string& mta, string& user)
    {
    	int p = s.find('@');
    	user = s.substr(0, p);
    	mta = s.substr(p + 1);
    }
    int main()
    {
    	string t;
    	set<string> addr;
    	while (cin >> t && t != "*")
    	{
    		string mta;
    		int n;
    		cin >> mta >> n;
    		while (n--)
    		{
    			string user;
    			cin >> user;
    			addr.insert(user + "@" + mta);//所有存在的用户和地址 
    		}
    	}
    	while (cin >> t && t != "*")
    	{
    		string mta, user;//发件地址 发件人
    		fen(t, mta, user);
    		//cout<<t<<" "<<mta<<" "<<user<<endl; 
    		set<string> shou;//收件地址和收件人 
    		vector<string> sd;//收件地址
    		map<string, vector<string> > mp;//相同收件地址的不同收件人及其收件地址 
    		while (cin >> t && t != "*")
    		{
    			if (shou.count(t))
    			{
    				continue;
    			}
    			shou.insert(t);
    			string mta2, user2;//收件地址和收件人 
    			fen(t, mta2, user2);
    			if (mp.count(mta2) == 0)
    			{
    				sd.push_back(mta2);
    				mp[mta2] = vector<string>();
    			}
    			mp[mta2].push_back(t);
    		}
    		getline(cin, t);
    		string mes;//文本 
    		while (getline(cin, t) && t != "*")
    		{
    			mes += "     " + t + "\n";//抄博友程序 
    		}
    		for (int i = 0; i < sd.size(); i++)//遍历收件人地址 
    		{
    			cout << "Connection between " << mta << " and " << sd[i] << endl;
    			cout << "     HELO " << mta << endl;
    			cout << "     250\n";
    			cout << "     MAIL FROM:<" << user << '@' << mta << ">\n";
    			cout << "     250\n";
    			int mark = 0;
    			vector<string> tv = mp[sd[i]];
    			for (int j = 0; j < tv.size(); j++)
    			{
    				cout << "     RCPT TO:<" << tv[j] << ">\n";
    				if (addr.count(tv[j])) { mark = 1; cout << "     250\n"; }//收件信息准确 
    				else cout << "     550\n";
    			}
    			if (mark)
    			{
    				cout << "     DATA\n     354\n";
    				cout << mes << "     .\n     250\n";
    			}
    			cout << "     QUIT\n     221\n";
    		}
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    877
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者