zoukankan      html  css  js  c++  java
  • 算法习题---5.11邮件传输代理的交互(Uva814)

    一:题目

    当某人从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 << "	HELO " << source_agent << endl << "	250" << endl;
                cout << "	MAIL FROM:<" << info << ">" << endl<<"	250"<<endl;
                
                int flag = 0;
                for (vector<string>::iterator it_re = (dest[*it]).begin(); it_re != (dest[*it]).end(); it_re++)    //遍历收件人
                {
                    cout << "	RCPT TO:<" << *it_re << "@" << *it << ">" << endl;
                    
                    if (!user_list.count(*it_re + "@" + *it))    //查找该用户是否存在
                        cout << "	550" << endl;
                    else
                    {
                        cout << "	250" << endl;
                        flag = 1;    //如果出现一个人有效,则正常输出数据
                    }
                }
                if (flag)    //如果出现一个人有效,则正常输出数据
                {
                    cout << "	DATA
    	354" << endl;
                    
                    for (vector<string>::iterator it_c = vec_cont.begin(); it_c != vec_cont.end();it_c++)
                        cout <<'	'<< *it_c << endl;
                    cout << "	." << endl << "	250" << endl;
                }
                cout << "	QUIT" << endl<<"	221"<<endl;
            }
        }
    
        freopen("CON", "r", stdin);
        freopen("CON", "w", stdout);
        return 0;
    }
    命名有点混乱
  • 相关阅读:
    Java 自动装箱与拆箱(Autoboxing and unboxing)【转】
    工厂方法和new
    java线程池【转】
    大型网站架构演化过程
    jsp el表达式
    GC垃圾回收
    mysql语句
    String StringBuilder StringBuffer
    粉丝关注数据库表的设计
    ECharts图表之柱状折线混合图
  • 原文地址:https://www.cnblogs.com/ssyfj/p/11523459.html
Copyright © 2011-2022 走看看