UVA ~ 814 ~ The Letter Carrier's Rounds (模拟 + map + set + vector)

题意:MTA意思是城市代理什么的。每个MTA会有一些用户。你把信息发到MTA,他会自动帮你转发给MTA里你需要发送的所有人。

先输入MTA和它对应的用户,以"*"结束。

然后输入一些请求,以"*"结束。

请求格式为:一堆"用户名@城市",第一个人(即发件人)要给后面所有的人(即收件人)发消息,"*"结束。再输入要发送的消息以"*"结束

对于每个请求,发件人会按照城市出现的顺序,把自己的城市与其进行连接。对于属于这个城市的收件人,如果存在输出250,不存在输出550。如果有人连接上了,就输出DATA和354,如果所有收件人都不存在,那么就不输出DATA。最后输出"."和QUIT和221。然后与下一个城市连接。

解释一下样例:

输入:

MTA London 4 Fiona Paul Heather Nevil       //表示London有4个用户Fiona Paul Heather Nevil
MTA SanFrancisco 3 Mario Luigi Shariff                   //表示SanFrancisco有3个用户Mario Luigi Shariff 
MTA Paris 3 Jacque Suzanne Maurice                      //表示Paris有3个用户Jacque Suzanne Maurice
MTA HongKong 3 Chen Jeng Hee                            //表示HongKong有3个用户Chen Jeng Hee 
MTA MexicoCity 4 Conrado Estella Eva Raul           //表示MexicoCity有3个用户Conrado Estella Eva Raul
MTA Cairo 3 Hamdy Tarik Misa                               //表示Cairo有3个用户Hamdy Tarik Misa

*

//第一个请求

Hamdy@Cairo Conrado@MexicoCity Shariff@SanFrancisco Lisa@MexicoCity

//Hamdy@Cairo要发信息给Conrado@MexicoCity,Shariff@SanFrancisco,Lisa@MexicoCity

*

Congratulations on your efforts !!--Hamdy               

//发送的消息

*

//第二个请求

Fiona@London Chen@HongKong Natasha@Paris

//Fiona@London要发信息给Chen@HongKong,Natasha@Paris

*

Thanks for the report! 

--Fiona

//发送的消息

*

*//结束

输出:

//处理第一个请求,发件人为Hamdy@Cairo

Connection between Cairo and MexicoCity        //     第一个出现的城市为MexicoCity,所先建立与它的连接
     HELO Cairo
     250
     MAIL FROM:<Hamdy@Cairo>                      //邮件的发件人
     250                                                                //发件人OK
     RCPT TO:<Conrado@MexicoCity>             //收件人Conrado@MexicoCity
     250                                                               //该收件人OK
     RCPT TO:<Lisa@MexicoCity>                    //收件人Lisa@MexicoCity
     550                                                               //Lisa不在MexicoCity,所以NO

//这个城市所有人进行连接结束之后开始发信息

     DATA
     354

     Congratulations on your efforts !!

     --Hamdy
     .                              //消息结束
     250                        //消息发送成功250(这个一定会成功的。。。)
     QUIT                      //这个城市处理结束
     221

Connection between Cairo and SanFrancisco                             //与第二个出现的城市SanFrancisco进行链接

     。。。。。。//这些跟前面基本都一样就省略了

//第一个请求处理结束,开始第二个请求

Connection between London and HongKong                            //与第一个出现的城市HongKong进行链接

     。。。。。。//这些跟前面基本都一样也省略了

可能解释会有问题,具体结合题目理解。

思路:参考紫书思路。MTA和人名转化为"用户名@城市"放入set。对于每一个请求,首先读入发件人,分离出MTA和用户名,然后读入所有收件人,把MTA按顺序存下来(用set判断是否出现过在前面,如果没出现过用vector存下来),用map保存MTA对应的收件人(即map<string, vector<string> > dest)。然后按MTA顺序(即vector)输出,每个MTA输出所有对应的收件人就行了。

吐槽一句题意真难理解,输出格式真麻烦。。。

#include<bits/stdc++.h>
using namespace std;
void parse_address(const string& addr, string& user, string& mta)
{
    int k = addr.find('@');
    user = addr.substr(0, k);
    mta = addr.substr(k + 1);
}
int main()
{
    string s, t, user1, user2, mta1, mta2;
    int k;
    set<string> addr;

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


    while (cin >> s && s != "*")
    {
        parse_address(s, user1, mta1);//处理发件人地址

        vector<string> mta;//按照顺序存储所有MTA
        map<string, vector<string> > dest;//每个MTA要发送的用户
        set<string> vis;
        while (cin >> t && t != "*")
        {
            if (vis.count(t)) continue;//重复的人
            parse_address(t, user2, mta2);//处理收件人地址
            vis.insert(t);
            if (!dest.count(mta2)) mta.push_back(mta2);
            dest[mta2].push_back(t);
        }
        cin.get();//吃回车

        //输入邮件正文
        string data;
        while (getline(cin, t) && t != "*") data += "     " + t + "\n";

        //输出
        for (auto i: mta)
        {
            mta2 = i;
            cout << "Connection between " + mta1 + " and " + mta2 << endl;
            cout << "     HELO " + mta1 << endl;
            cout << "     250\n";
            cout << "     MAIL FROM:<" + s + ">\n";
            cout << "     250\n";
            bool ok = false;
            for (auto j: dest[mta2])
            {
                cout << "     RCPT TO:<" << j << ">\n";
                if (addr.count(j)) { ok = true; cout << "     250\n"; }
                else cout << "     550\n";
            }
            if (ok)
            {
                cout << "     DATA\n";
                cout << "     354\n";
                cout << data;
                cout << "     .\n";
                cout << "     250\n";
            }
            cout << "     QUIT\n";
            cout << "     221\n";
        }
    }
    return 0;
}
/*
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
*
*
*/




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值