UVA 814 The Letter Carrier's Rounds
大致翻译:
对于电子邮件应用程序,您需要描述发生在成对mta之间的基于smtp的通信。发送方
的用户代理向发送消息传输代理(MTA)提供格式化的消息。发送MTA使用SimpleMail
传输协议(SMTP)与接收MTA通信。接收MTA将邮件发送到接收方的用户代理。初始化
通信链路后,发送MTA将命令行(每次一行)传输到接收MTA,接收MTA在处理每个命令
后返回一个三位数编码的响应。下面按每个消息的发送顺序显示这些发送命令。当
同一消息发送到同一MTA的多个用户时,会有多个RCPTTO行。给不同mta的用户的消
息需要单独的SMTP会话。
输入
输入包含mta的描述以及任意数量的消息。每个MTA的描述以MTA目的地及其名称(1到
15个字母数字字符)开始。在MTA名称后面是在该MTA接收邮件的用户数量和用户列表
(每个用户1到15个字母数字字符)。MTA描述以第1列中的星号结束。每条消息都以发
送用户的姓名开始,然后是收件人标识符列表。每个标识符的表单是user@mtaname
。消息(每行包含不超过72个字符)以第1列中的星号开始和结束。第1列中带有星号
而不是发送方和接收方列表的行表示整个输入的结束。
输出
对于每个消息,显示发送和接收mta之间的通信。消息中提到的每个MTA都是有效的
MTA;但是,目的地MTA可能不存在消息接收者。接收MTA通过使用550代码响应RCPT
to命令拒绝这些用户的邮件。拒绝将不影响在同一MTA向授权用户交付。如果在特定
的MTA上没有至少一个授权的收件人,则数据不会被发送。只有一个SMTP会话用于向
特定MTA的用户发送消息。例如,发送给同一MTA的5个用户的消息将只有一个SMTP会
话。同样,一条消息只针对同一用户一次。发送方联系接收mta的顺序与输入文件中
的顺序相同。如示例输出所示,在通信前加上正在通信的MTA名称,并缩进每个非空
通信行。不应打印不必要的空格。
样例输入:
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
*
Congratulations on your efforts !!
--Hamdy
*
Fiona@London Chen@HongKong Natasha@Paris
*
Thanks for the report!
--Fiona
*
*
样例输出:(中间没有空行,是截图的锅)
1 #include<iostream> 2 #include<string> 3 #include<vector> 4 #include<set> 5 #include<map> 6 using namespace std; 7 8 void parse_address(const string &s,string & user,string &mta) 9 { 10 int pos = s.find('@');//从0开始 11 user = s.substr(0, pos);//左闭右开,复制0~pos-1; 12 mta = s.substr(pos + 1); 13 } 14 int main() 15 { 16 set<string> addr; 17 string s,s2,user1,mta1,user2,mta2; 18 int n; 19 while (cin >> s&&s != "*")//MTA,第一个* 20 { 21 cin >> s >> n; 22 while (n--) 23 { 24 cin >> s2; 25 addr.insert(s2 + "@" + s);//Hamdy@Cairo这样存 26 } 27 } 28 while (cin>>s&&s!="*")//发件人收件人,数据,第五个* 29 { 30 parse_address(s, user1, mta1);//分割Hamdy@Cairo发件人 31 32 vector<string> mta;//所有需要连接的MTA(按输入顺序) 33 map<string, vector<string> > dest;//每个MTA需要发送的用户 34 //<MTA名称,用户名列表> 35 set<string> vis;//收件人去重 36 37 while (cin>>s2&&s2!="*")//处理收件人,第二个* 38 { 39 parse_address(s2, user2, mta2);//分割收件人 40 if (vis.count(s2))//重复的收件人 41 continue; 42 vis.insert(s2); 43 44 if (!dest.count(mta2)) 45 { 46 mta.push_back(mta2); 47 dest[mta2] = vector<string>(); 48 } 49 dest[mta2].push_back(s2); 50 } 51 getline(cin, s2);//取数据前面的*的回车,第三个* 52 53 string data;//正文数据 54 while (getline(cin, s2) && s2[0] != '*')//第四个* 55 data += " " + s2 + "\n"; 56 57 for (int i = 0; i < mta.size(); i++) 58 { 59 string mta2; 60 mta2 = mta[i]; 61 vector<string> users = dest[mta2]; 62 cout << "Connection between " <<mta1 << " and " <<mta2 << endl; 63 cout << " HELO " << mta1 << "\n"; 64 cout << " 250" << endl; 65 cout <<" MAIL FROM:<" <<s<< ">"<<endl; 66 cout << " 250" << endl; 67 68 bool ok = false; 69 for (int j = 0; j < users.size(); j++) 70 { 71 cout << " RCPT TO:<" << users[j] <<">"<< endl; 72 if (addr.count(users[j])) 73 { 74 ok = true; 75 cout << " 250" << endl; 76 } 77 else 78 cout << " 550" << endl; 79 } 80 if (ok) 81 { 82 cout << " DATA" << endl; 83 cout << " 354" << endl; 84 cout << data; 85 cout << " ."<<endl; 86 cout << " 250" << endl; 87 } 88 cout << " QUIT" << endl; 89 cout << " 221" << endl; 90 } 91 92 } 93 94 return 0; 95 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步