hiho一下第171周《Email Merge》

http://hihocoder.com/contest/hiho171/problem/1

时间限制: 10000ms
单点时限: 1000ms
内存限制: 256MB

描述

You are given a list of usernames and their email addresses in the following format:

alice 2 alice@hihocoder.com alice@gmail.com
bob 1 bob@qq.com
alicebest 2 alice@gmail.com alice@qq.com
alice2016 1 alice@qq.com

Your task is to merge the usernames if they share common email address:

alice alicebest alice2016
bob

输入

The first lines contain an integer N, denoting the number of usernames. (1 < N ≤ 10000)

The following N lines contain N usernames and their emails in the previous mentioned format.

Each username may have 10 emails at most.

输出

Output one merged group per line.

In each group output the usernames in the same order as the input.

Output the groups in the same order as their first usernames appear in the input.

样例输入
4 alice 2 alice@hihocoder.com alice@gmail.com
bob 1 bob@qq.com
alicebest 2 alice@gmail.com alice@qq.com
alice2016 1 alice@qq.com 
样例输出
alice alicebest alice2016
bob 
给一个数n 随后给n行数据,每行数据第一个字符串是用户名,随后一个数字t  , 接下来t个字符串是该用户名的邮箱。

让我们输出是同一个用户的所有用户名。

一个用户名占一行。

个人思路是用一个结构体把用户名和邮箱保存,然后用并查集组合起来,但是邮箱是字符串如果一个个比较过去字符串的长度可能会超时所以我用map把邮箱地址hash成数字这样每一个字符串就只有O(1)的比较时间

(目前只过了百分之40的数据,已经排除了重复用户名的可能性)当前代码。

#include <iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<map>
#include<vector>
using namespace std;
struct node{
        string usename;
        int num;
        vector<int>email;
};
node use[10010];
int find(int x)
{
        int r=x;
        while(use[r].num!=r)
                r=use[r].num;
        int i=x,j;
        while(use[i].num!=r){
                j=use[i].num;
                use[i].num=r;
                i=j;
        }
        return r;
}
void join(int x,int y){
        int fx=find(x),fy=find(y);
        if(fx!=fy)
                use[fy].num=fx;
}
int main()
{
        map<string,int>my;
        string usename,email;
        int n;
        int t;
        scanf("%d",&t);
        int cnt=1;
        int pop;
        int cntt=0;
        for(int i=0;i<t;i++){
                cin>>usename;
                pop=i;
                cntt++;
                for(int k=0;k<i;k++){
                        if(use[k].usename==usename){
                                pop=k;
                                cntt--;
                                break;
                        }
                }
                use[pop].usename=usename;
                use[pop].num=pop;
                scanf("%d",&n);
                for(int j=0;j<n;j++){
                        cin>>email;
                        if(!my[email])
                                my[email]=cnt++;
                        use[pop].email.push_back(my[email]);
                }
        }
        for(int i=0;i<cntt;i++){
                for(int j=i+1;j<cntt;j++){
                                if(use[i].num==use[j].num)
                                continue;
                        for(int k=0;k<use[i].email.size();k++){
                                for(int l=0;l<use[j].email.size();l++){
                                        if(use[i].email[k]==use[j].email[l]){
                                                join(i,j);
                                        }
                                }
                        }
                }
        }
        for(int i=0;i<cntt;i++){
                if(use[i].num==i)
                {
                        cout<<use[i].usename<<" ";
                        for(int j=i+1;j<cntt;j++){
                                if(use[j].num==i)
                                        cout<<use[j].usename<<" ";
                        }
                        cout<<endl;
                }
        }return 0;
}

修复了一个bug多过了一组数据。。

#include <iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<map>
#include<vector>
using namespace std;
struct node{
        string usename;
        int num;
        vector<int>email;
};
node use[10010];
int find(int x)
{
        int r=x;
        while(use[r].num!=r)
                r=use[r].num;
        int i=x,j;
        while(use[i].num!=r){
                j=use[i].num;
                use[i].num=r;
                i=j;
        }
        return r;
}
void join(int x,int y){
        int fx=find(x),fy=find(y);
        if(fx!=fy)
                use[fy].num=fx;
}
int main()
{
        map<string,int>my;
        string usename,email;
        int n;
        int t;
        scanf("%d",&t);
        int cnt=1;
        int pop;
        int cntt=0;
        for(int i=0;i<t;i++){
                cin>>usename;
                pop=cntt++;
                for(int k=0;k<i;k++){
                        if(use[k].usename==usename){
                                pop=k;
                                cntt--;
                                break;
                        }
                }
         //       cout<<usename<<endl;
                use[pop].usename=usename;
                use[pop].num=pop;
                scanf("%d",&n);
                for(int j=0;j<n;j++){
                        cin>>email;
                        if(!my[email])
                                my[email]=cnt++;
                        use[pop].email.push_back(my[email]);
                }
        }
       // printf("cntt==%d\n",cntt);
        for(int i=0;i<cntt;i++){
                for(int j=i+1;j<cntt;j++){
                                if(use[i].num==use[j].num)
                                        continue;
                        for(int k=0;k<use[i].email.size();k++){
                                for(int l=0;l<use[j].email.size();l++){
                                        if(use[i].email[k]==use[j].email[l]){
                                                join(i,j);
                                        }
                                }
                        }
                }
        }
 /*       for(int i=0;i<cntt;i++){
                printf("use[%d].usename=",i);
                cout<<use[i].usename;
                printf("  use[%d].num==%d   ",i,use[i].num);
                cout<<endl;
        }*/
        int flag[10010];
        memset(flag,0,sizeof(flag));
        for(int i=0;i<cntt;i++){
                if(flag[use[i].num]==0)
                {
                        cout<<use[i].usename<<" ";
                        for(int j=i+1;j<cntt;j++){
                                if(use[j].num==use[i].num)
                                        cout<<use[j].usename<<" ";
                        }
                        cout<<endl;
                        flag[use[i].num]=1;
                }
        }return 0;
}


更新,修复了一个很蠢的错误,并查集应该是搜索find是否相同,改完之后数据过了百分之90

#include <iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<map>
#include<vector>
using namespace std;
struct node{
        string usename;
        int num;
        vector<int>email;
};
node use[10010];
int find(int x)
{
        int r=x;
        while(use[r].num!=r)
                r=use[r].num;
        int i=x,j;
        while(use[i].num!=r){
                j=use[i].num;
                use[i].num=r;
                i=j;
        }
        return r;
}
void join(int x,int y){
        int fx=find(x),fy=find(y);
        if(fx!=fy)
                use[fy].num=fx;
}
int main()
{
        map<string,int>my;
        string usename,email;
        int n;
        int t;
        scanf("%d",&t);
        int cnt=1;
        int pop;
        int cntt=0;
        for(int i=0;i<t;i++){
                cin>>usename;
                pop=cntt++;
                for(int k=0;k<i;k++){
                        if(use[k].usename==usename){
                                pop=k;
                                cntt--;
                                break;
                        }
                }
                use[pop].usename=usename;
                use[pop].num=pop;
                scanf("%d",&n);
                for(int j=0;j<n;j++){
                        cin>>email;
                        if(!my[email])
                                my[email]=cnt++;
                        use[pop].email.push_back(my[email]);
                }
        }
        for(int i=0;i<cntt;i++){
                for(int j=i+1;j<cntt;j++){
                                if(find(use[i].num)==find(use[j].num))
                                        continue;
                        for(int k=0;k<use[i].email.size();k++){
                                for(int l=0;l<use[j].email.size();l++){
                                        if(use[i].email[k]==use[j].email[l]){
                                                join(i,j);
                                                break;
                                        }
                                }
                        }
                }
        }
        int flag[10010];
        memset(flag,0,sizeof(flag));
        for(int i=0;i<cntt;i++){
                if(flag[find(use[i].num)]==0)
                {
                        cout<<use[i].usename<<" ";
                        for(int j=i+1;j<cntt;j++){
                                if(find(use[i].num)==find(use[j].num))
                                        cout<<use[j].usename<<" ";
                        }
                        cout<<endl;
                        flag[use[i].num]=1;
                }
        }return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值