阿里编程测试之关系
昨天做了阿里内推的编程测试,题目大致意思如下:
定义一个关系对集合
S = {(A,B),(B,J),(C,D),(E,F),(G,H),(H,I),(I,J)}
,每一个关系对之间的关系可以是同事,同学,老乡等。关系间的距离可以定义为到达对方所需的最小步数,即AB之间距离为1,AJ之间距离为2.请写一个函数,实现如下功能:给定两个人x和y,一个数字d,判断这两个人在距离d内存不存在关系。
输入输出示例:
A I 2 => false
A I 3 => true
首先我想到的就是用图去做,但是当时看到默认编辑器中提供了map,转念一想,那岂不是让我用map去做?只两个人x,y之间存不存在一条通路不就可以了吗?也就是:
x->x1->x2->x3->...->y,对其中任意的连续对p,q,存在map[p] = q。
我傻傻地这样做了。做完才发现,测试用例通不过,这时才想到,用普通的map方法,默认了关系是有向图,而事实上,关系是无向图。但是当时已经没多少时间了,我匆匆瞎改了一些东西就提交了。
今天我又复习了一下数据结构中图的知识,重新做了一遍,思路大概如下:
- 先根据给定的关系,建立一张无向图,图可以用邻接矩阵或者邻接表来表示,我这里选用的是邻接矩阵,因为节点数不多,而且建立也方便。
- 然后对指定结点进行遍历(不需要遍历所有结点),有深度优先遍历和广度优先遍历,应该都是可以选的,我选择的是深度优先实现,按理说广度优先应该更符合一点。但是也都差不多了。
- 设置一个标志,用来标记有没有找到。给定距离d及目标,每次深度优先的时候减一,如果到0了还没找到,就返回;如果找到了就将标志位置为真。
- 等到遍历完成之后,判断标志位置是否为真,如果是真,那么找到了,否则就是没找到,也就是说在制定距离内二者没有关系。
代码如下:
#include<map>
#include<iostream>
#define MAXSIZE 15
using namespace std;
struct Graph{
char vex[MAXSIZE];
int arcs[MAXSIZE][MAXSIZE];
int arcNums,vexNums;
};
void initGraph(Graph &g){
//因为题目中已经给出了图的基本信息,这里就直接用来初始化了
g.arcNums = 7;
g.vexNums = 10;
//存储结点
for(int i = 0;i<g.vexNums;i++)
g.vex[i] = 'A'+i;
//强行用map来初始化邻接矩阵
map<int,int> mp;
mp[0] = 1; //A B 同事,同学等
mp[1] = 9; //B J
mp[2] = 3; //C D
mp[4] = 5; //E F
mp[6] = 7; //G H
mp[7] = 8; //H I
mp[8] = 9; //I J
//先初始化为0
for (int i = 0; i < g.vexNums; i++) {
for (int j = 0; j < g.vexNums; j++) {
g.arcs[i][j] = 0;
}
}
//无向图是对称的
for (int i = 0; i < g.vexNums; i++) {
if (mp[i] != 0) {
g.arcs[i][mp[i]] = g.arcs[mp[i]][i] = 1;
}
}
}
//全局访问数组
bool visited[MAXSIZE] = {false};
void dfs(const Graph &g,int i, int dis,char des,bool &flag){
//普通的dfs,只不过加了距离判断和标志位
visited[i] = true;
//cout<<"Now visiting node: "<<g.vex[i]<<endl;
for(int j = 0;j<g.vexNums;j++){
//要保证每次循环时dis不被改变
int temp = dis;
if(temp!=0 && g.arcs[i][j]==1 && !visited[j]){
if(g.vex[j]==des){
flag = true;
return;
}
else
dfs(g,j,--temp,des,flag);
}
}
}
void dfsTraverse(Graph &g,int start,int dis,char des){
bool flag = false;
dfs(g,start,dis,des,flag);
if(flag)
cout<<"True"<<endl;
else
cout<<"False"<<endl;
}
int main(){
Graph g;
initGraph(g);
char startc = 'A';
char des = 'I';
int dis = 3;
cin>>startc>>des>>dis;
int start = startc-'A';
dfsTraverse(g,start,dis,des);
return 0;
}