pat甲级1139. First Contact (30)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/richenyunqi/article/details/79595547

欢迎访问我的pat甲级题解目录哦https://blog.csdn.net/richenyunqi/article/details/84981078

题目描述

题意分析

可以把整个题目描述表示成一个图,每个人都是其中一个结点,两个人如果是朋友则在两个人之间有一条边。题目要求的就是给定一个起始结点,一个末尾结点,能不能找到两个结点,使得从起始结点出发经过这两个结点之后到达末尾结点。当然,题目要求比这个稍微复杂,每个节点有男、女两种性别,而且要求经过的两个节点中,第一个节点的性别和起始结点一致,第二个结点的性别和末尾结点一致。

算法设计

由于最后要先按第一个结点从小到大排序,再按第二个节点从小到大排序,可以直接使用c++标准库中的pair类型保存这两个节点,因为pair类型自定义的<运算符恰好就是先按第一个元素从小到大排序,再按第二个元素从小到大排序。由于只要求首尾结点之间有两个结点,且结点总数最多才300个,可以直接采取暴力搜索的方法,在搜索过程中,注意保证第一个节点和首结点性别相同,第二个节点和末尾结点性别相同,此外要避免过早达到头结点或返回首节点的情况出现。具体实现可见代码,非常简洁易懂哦~~

注意点

(1)有一个大坑,题目按给定的4位数字前有无‘-’号作为区别男女的标志,有一个测试点包含了-0000这样的数据,如果用int读入,是不会认为它是一个负数的,于是程序自然把其代表的人视作了女性,导致了错误。所以为了保证正确,最好用char数组或者string读入,以确保前面的'-' 号不会丢失。

(2)输出结点值时要按"%04d"的形式输出,以保证输出数字有4位,不足在高位补0

(3)形成的图为无向图,边为无向边

(4)搜索过程中避免过早达到头结点或返回首节点的情况出现,即保证搜索的两个结点既不等于首节点,也不等于尾结点

C++代码

#include <bits/stdc++.h>
using namespace std;
vector<int>graph[10005];//图
bool boy[10005];//下标为ID,元素表示该ID是否是男
int N,M,K,vstart,vend;
int main(){
    scanf("%d%d",&N,&M);
    for(int i=0;i<M;++i){//读取边的数据
        string a,b;
        cin>>a>>b;
        int ia=abs(stoi(a)),ib=abs(stoi(b));//将字符串化为正整数
        graph[ia].push_back(ib);//向图中加入边
        graph[ib].push_back(ia);//向图中加入边
        boy[ia]=(a[0]!='-');//表示该人性别
        boy[ib]=(b[0]!='-');//表示该人性别
    }
    scanf("%d",&K);
    while(K--){
        scanf("%d%d",&vstart,&vend);//读取首尾结点
        vector<pair<int,int>>result;//存储符合题目要求的两个结点
        for(int i:graph[abs(vstart)])//遍历首节点的朋友
            if(i!=abs(vend)&&i!=abs(vstart)&&boy[i]==boy[abs(vstart)])//找到非首尾结点且与首节点性别相同的朋友作为第一个节点
                for(int j:graph[i])//遍历第一个节点的朋友
                    if(j!=abs(vend)&&j!=abs(vstart)&&boy[j]==boy[abs(vend)])//找到非首尾结点且与尾节点性别相同的朋友作为第二个节点
                        for(int k:graph[j])//遍历第二个节点的朋友
                            if(k==abs(vend))//尾结点是第二个节点的朋友
                                result.push_back({i,j});//i,j两个节点符合要求
        printf("%d\n",result.size());
        sort(result.begin(),result.end());//排序
        for(auto&i:result)//输出
            printf("%04d %04d\n",i.first,i.second);
    }
    return 0;
}

 

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试

关闭