1139 First Contact (30 分)

问题描述:A联系B,需要通过A的朋友C和C与B的朋友D,即A->C->D->B;

解题思路:可以用图也可以用集合,将a的朋友分为同性朋友和异性朋友,这样便于以后查找。注意-0和0不一样。

AC代码:

#include<iostream>
#include<unordered_map>
#include<unordered_set>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
#define MAX 310
typedef struct node{
    int a,b;
    node(int x,int y):a(x),b(y){}
}node;
vector<node>out;
unordered_map<string,unordered_set<string> >dge,sge;//dge不同性别,sge相同性别
bool cmp(node &a,node &b)
{
    if(a.a==b.a)return a.b<b.b;
    else return a.a<b.a;
}
int main()
{
    freopen("test.txt","r",stdin);
    int N,M,K;
    string s1,s2;
    scanf("%d %d",&N,&M);
    while(M--){
        cin>>s1>>s2;
        if(s1.length()==s2.length()){
            sge[s1].insert(s2);
            sge[s2].insert(s1);
        }else{
            dge[s1].insert(s2);
            dge[s2].insert(s1);
        }
    }
    scanf("%d",&K);
    while(K--){
        out.clear();
        cin>>s1>>s2;
        unordered_set<string>::iterator i,j;
        if(sge.count(s1)&&sge.count(s2)){
            for(i=sge[s1].begin();i!=sge[s1].end();++i){//A同性中查找朋友
                for(j=sge[s2].begin();j!=sge[s2].end();++j){//B在同性中查找朋友
                    if(*(i)==s1||*(j)==s2)continue;//一个典型例子A——B,当i=b,j=a,时显然不满足。
                    if(s1.length()==s2.length()){//AB同性,则要求CD不是同一个人,而且还是朋友
                        if(*(i)!=*(j)&&sge[*(j)].count(*(i)))out.push_back(node(abs(stoi(*(i))),abs(stoi(*(j)))));
                    }else{//异性则CD只需是朋友
                        if(dge[*(j)].count(*(i)))out.push_back(node(abs(stoi(*(i))),abs(stoi(*(j)))));
                    }
                }
            }
        }
        sort(out.begin(),out.end(),cmp);
        printf("%d\n",out.size());
        for(unsigned k=0;k<out.size();++k)printf("%d %d\n",out[k].a,out[k].b);
    }
    return 0;
}

两个错误

//#1集合的思想,有错误
#include<iostream>
#include<unordered_map>
#include<unordered_set>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
#define MAX 310
typedef struct node{
    int a,b;
    node(int x,int y):a(x),b(y){}
}node;
string id[MAX];
vector<node>out;
unordered_map<int,int>num;
unordered_set<int>dge[MAX],sge[MAX];
bool cmp(node &a,node &b)
{
    if(a.a==b.a)return a.b<b.b;
    else return a.a<b.a;
}
int main()
{
    freopen("test.txt","r",stdin);
    int N,M,K,cnt=0,f1,f2;
    string s1,s2;
    scanf("%d %d",&N,&M);
    while(M--){
        cin>>s1>>s2;
        f1=abs(stoi(s1));f2=abs(stoi(s2));
        if(!num.count(f1)){num[f1]=cnt++;id[cnt-1]=s1;}
        if(!num.count(f2)){num[f2]=cnt++;id[cnt-1]=s2;}
        if(s1.length()==s2.length()){
            sge[num[f1]].insert(f2);
            sge[num[f2]].insert(f1);
        }else{
            dge[num[f1]].insert(f2);
            dge[num[f2]].insert(f1);
        }
    }
    scanf("%d",&K);
    while(K--){
        out.clear();
        cin>>s1>>s2;
        f1=abs(stoi(s1));f2=abs(stoi(s2));
        unordered_set<int>::iterator i,j;
        for(i=sge[num[f1]].begin();s1==id[num[f1]]&&i!=sge[num[f1]].end();++i){
            for(j=sge[num[f2]].begin();s2==id[num[f2]]&&j!=sge[num[f2]].end();++j){
                if(s1.length()==s2.length()){
                    if(*(i)!=*(j)&&sge[num[*(j)]].count(*(i)))out.push_back(node(*(i),*(j)));
                }else{
                    if(*(i)!=*(j)&&dge[num[*(j)]].count(*(i)))out.push_back(node(*(i),*(j)));
                }
            }
        }
        sort(out.begin(),out.end(),cmp);
        printf("%d\n",out.size());
        for(unsigned k=0;k<out.size();++k)printf("%d %d\n",out[k].a,out[k].b);
    }
    return 0;
}

//#2图的思想,有错
#include<iostream>
#include<algorithm>
#include<unordered_map>
#include<vector>
#include<cmath>
#include<cstring>
using namespace std;
#define MAX 310
unordered_map<int,int>num;
bool gra[MAX][MAX]={0};
vector<int>man,woman;
vector<pair<int,int> >out;
//查询时性别不同,但id相同
void findCD(bool ga,int a,bool gb,int b)//
{
    int i,j,x,y;
    out.clear();
    if(ga){//本来是女,但是查询输入一个男的相同id
        for(i=0;i<man.size();++i){
            x=man[i];
            if(gra[num[a]][num[x]]){
                if(!gb){ //男女
                    for(j=0;j<woman.size();++j){
                        y=woman[j];
                        if(gra[num[x]][num[y]]&&gra[num[y]][num[b]]){
                            out.push_back(make_pair(x,y));
                        }
                    }
                }else{ //男男
                    for(j=0;j<man.size();++j){
                        y=man[j];
                        if(j!=i&&gra[num[x]][num[y]]&&gra[num[y]][num[b]]){
                            out.push_back(make_pair(x,y));
                        }
                    }
                }
            }
        }
    }else{//a为女
        for(i=0;i<woman.size();++i){
            x=woman[i];
            if(gra[num[a]][num[x]]){
                if(!gb){//女女
                    for(j=0;j<woman.size();++j){
                        y=woman[j];
                        if(j!=i&&gra[num[x]][num[y]]&&gra[num[y]][num[b]]){
                            out.push_back(make_pair(x,y));
                        }
                    }
                }else{//女男
                    for(j=0;j<man.size();++j){
                        y=man[j];
                        if(gra[num[x]][num[y]]&&gra[num[y]][num[b]]){
                            out.push_back(make_pair(x,y));
                        }
                    }
                }
            }
        }
    }
    printf("%d\n",out.size());
    for(i=0;i<out.size();++i)printf("%04d %04d\n",out[i].first,out[i].second);
}
int main()
{
    freopen("test.txt","r",stdin);
    int N,M,K,f1,f2,cnt=0;
    string s1,s2;
    scanf("%d %d",&N,&M);
    while(M--){
        cin>>s1>>s2;
        f1=abs(stoi(s1));f2=abs(stoi(s2));
        if(!num.count(f1)){
            num[f1]=++cnt;
            if(s1.length()==4)man.push_back(f1);
            else woman.push_back(f1);
        }
        if(!num.count(f2)){
            num[f2]=++cnt;
            if(s2.length()==4)man.push_back(f2);
            else woman.push_back(f2);
        }
        gra[num[f1]][num[f2]]=gra[num[f2]][num[f1]]=1;
    }
    sort(man.begin(),man.end());
    sort(woman.begin(),woman.end());
    scanf("%d",&K);
    while(K--){
        cin>>s1>>s2;
        bool g1,g2;
        f1=abs(stoi(s1));f2=abs(stoi(s2));
        if(s1.length()==4)g1=1;
        else g1=0;
        if(s2.length()==4)g2=1;
        else g2=0;
        findCD(g1,f1,g2,f2);
    }
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值