hiho一下第171周《Email Merge》

来源:互联网 发布:回形针淘宝店面设计图 编辑:程序博客网 时间:2024/06/06 13:13

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.combob 1 bob@qq.comalicebest 2 alice@gmail.com alice@qq.comalice2016 1 alice@qq.com 
样例输出
alice alicebest alice2016bob 
给一个数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;}


原创粉丝点击