一:题目
当某人从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 London 4 Fiona Paul Heather Nevil //MTA无意义 第一个London是邮件传输代理 4 代表有四个用户 Fiona Paul Heather Nevil MTA SanFrancisco 3 Mario Luigi Shariff MTA Paris 3 Jacque Suzanne Maurice MTA HongKong 3 Chen Jeng Hee MTA MexicoCity 4 Conrado Estella Eva Raul MTA Cairo 3 Hamdy Tarik Misa * Hamdy@Cairo Conrado@MexicoCity Shariff@SanFrancisco Lisa@MexicoCity //第一个Hamdy@Cairo表示发件人 后面全是收件人(注意:收件人可能不存在) * //分割符 Congratulations on your efforts !! --Hamdy //在遇到下面一个*之前的内容全是发送邮件内容 * Fiona@London Chen@HongKong Natasha@Paris //这是第二组邮件发送,和上面一致 * Thanks for the report! --Fiona * * //结束标识
(二)样例输出
Connection between Cairo and MexicoCity HELO Cairo 250 MAIL FROM:<Hamdy@Cairo> 250 RCPT TO:<Conrado@MexicoCity> 250 //注意:当一次给多个发送时,只要有一个用户是有效的:下面都要写出发送内容。若是都无效,则像最下面的那样,不输出内容,直接退出 RCPT TO:<Lisa@MexicoCity> 550 //注意: DATA 354 Congratulations on your efforts !! --Hamdy . 250 QUIT
221 Connection between Cairo and SanFrancisco HELO Cairo 250 MAIL FROM:<Hamdy@Cairo> 250 RCPT TO:<Shariff@SanFrancisco> 250 DATA 354 Congratulations on your efforts !! --Hamdy . 250 QUIT
221 Connection between London and HongKong HELO London 250 MAIL FROM:<Fiona@London> 250 RCPT TO:<Chen@HongKong> 250 DATA 354 Thanks for the report! --Fiona . 250 QUIT
221 Connection between London and Paris HELO London 250 MAIL FROM:<Fiona@London> 250 RCPT TO:<Natasha@Paris> 550 QUIT //直接退出
221
注意:状态码含义
221 Closing connection (after QUIT) //关闭连接
250 Action was okay (after MAIL FROM and RCPT TO specifying an acceptable user, or completion
of a message) //行为未出错
354 Start sending mail (after DATA) //开始传输邮件
550 Action not taken; no such user here (after RCPT TO with unknown user) //行为出错,没有该用户
二:代码实现
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #include <set> #include <map> #include <vector> using namespace std; int main() { freopen("data5_11.in", "r", stdin); freopen("data5_11.out", "w", stdout); string info,agent,user,Uname,Eagt,content,source_agent; int num; //列表个数 set<string> user_list; while (cin >> info&&info != "*") //1.获取所有的MTA用户列表 { cin >> agent>> num; for (int i = 0; i < num; i++) { cin >> user; user_list.insert(user+"@"+agent); //用于后面检测用户存在 } } while (cin >> info&&info != "*") //发送方存放在info中 { source_agent = info.substr(info.find('@')+1); //获取接收方信息 map<string, vector<string> >dest; vector<string> dest_agt; //接收方代理 set<string> dest_fullinfo; //防止重复发送 while (cin >> Uname&&Uname != "*") //发送方存放在info中 { if (dest_fullinfo.count(Uname)) //防止重复发送 continue; dest_fullinfo.insert(Uname); Eagt = Uname.substr(Uname.find('@')+1); Uname = Uname.substr(0, Uname.find('@')); if (!dest.count(Eagt)) //如果代理是第一次出现 { dest_agt.push_back(Eagt); dest[Eagt] = vector<string>(); } (dest[Eagt]).push_back(Uname); //插入新的用户 } vector<string> vec_cont; //获取发送内容 getchar(); //将前一个回车吃掉 while (getline(cin,content)&&content!="*") vec_cont.push_back(content); for (vector<string>::iterator it = dest_agt.begin(); it != dest_agt.end(); it++) //进行信息发送 { cout << "Connection between " << source_agent << " and " << *it << endl; cout << "\tHELO " << source_agent << endl << "\t250" << endl; cout << "\tMAIL FROM:<" << info << ">" << endl<<"\t250"<<endl; int flag = 0; for (vector<string>::iterator it_re = (dest[*it]).begin(); it_re != (dest[*it]).end(); it_re++) //遍历收件人 { cout << "\tRCPT TO:<" << *it_re << "@" << *it << ">" << endl; if (!user_list.count(*it_re + "@" + *it)) //查找该用户是否存在 cout << "\t550" << endl; else { cout << "\t250" << endl; flag = 1; //如果出现一个人有效,则正常输出数据 } } if (flag) //如果出现一个人有效,则正常输出数据 { cout << "\tDATA\n\t354" << endl; for (vector<string>::iterator it_c = vec_cont.begin(); it_c != vec_cont.end();it_c++) cout <<'\t'<< *it_c << endl; cout << "\t." << endl << "\t250" << endl; } cout << "\tQUIT" << endl<<"\t221"<<endl; } } freopen("CON", "r", stdin); freopen("CON", "w", stdout); return 0; }
命名有点混乱