好友推荐
有n个人,每个人都有各自的好友列表。给定一个阈值p,当A和B的共同好友数超过p则推荐A和B为好友。请实现自动推荐直到没有好友可以推荐(每次推荐默认同意,即一定成为好友),然后进行一些查询。
查询1:A的好友数有几个?如果A不在这n个里面,输出-1,否则输出好友数;
查询2:A和B是好友吗?如果是则输出0,否则输出-1。
输入:p n m x y
p为阈值,n为人数,m为初始时的好友,x为查询1的个数,y为查询2的个数
注:
- 如果A是B的好友,B一定是A的好友;
- 每个人的人名用不超过20个字符的字符串表示,没有重名的人;
- 人数不超过100.
输入示例:
2 3 3 3 3
A
B
C
A B
B C
A C
A
B
C
A B
C A
B C
应输出:
2
2
2
0
0
0
public class Main{
public static class User{
String name;
int friend;
}
public static int name2Index(String name,String[] users){
int i,len=users.length;
for(i=0;i<len;++i){
if(users[i].equals(name))
return i;
}
return -1;
}
public static void recommend(String[] users,boolean[][] relation,int p){
int i,j,k;
int friendNum=0;
int userNum=users.length;
boolean flag=true;
while(flag){
flag=false;
for(i=0;i<userNum;++i){
for(j=0;j<userNum;++j){
if(i==j||relation[i][j]){// 如果i,j已经是朋友,没必要推荐,自己和自己也没必要推荐
continue;
}
friendNum=0;
for(k=0;k<userNum;++k){
if(i!=k&&j!=k&&relation[i][k]&&relation[j][k]){// i,j同时是k的朋友
friendNum++;// 共同好友数+1
}
}
if(friendNum>=p){// 共同好友数大于阈值,将i,j推荐给对方
relation[i][j]=true;
relation[j][i]=true;
flag=true;
}
}
}
}
}
public static int queryFriendNum(String name,String[] users,boolean[][] relation){
int idx=name2Index(name, users);
if(idx==-1)
return -1;
int len=relation.length;
int num=0;
for(int j=0;j<len;++j){
if(relation[idx][j])
num++;
}
return num;
}
public static int isFriend(String name1,String name2,String[] users,boolean[][] relation){
int idx1=name2Index(name1, users);
int idx2=name2Index(name2, users);
if(relation[idx1][idx2])
return 0;
return -1;
}
public static void main(String[] args){
int p,n,m,x,y;
int i;
String[] users;
boolean[][] relation;
try(Scanner sc=new Scanner(System.in)){
p=sc.nextInt();// 阈值
n=sc.nextInt();// 用户数
m=sc.nextInt();// 初始好友
x=sc.nextInt();// 查询1个数
y=sc.nextInt();// 查询2个数
users=new String[n];
relation=new boolean[n][n];// 邻接矩阵
// 输入用户
for(i=0;i<n;++i){
users[i]=sc.next();
}
// 输入初始好友关系
String name1,name2;
int idx1,idx2;
for(i=0;i<m;++i){
name1=sc.next();
name2=sc.next();
idx1=name2Index(name1, users);
idx2=name2Index(name2, users);
relation[idx1][idx2]=true;
relation[idx2][idx1]=true;// 好友关系是双向的
}
// 推荐好友
recommend(users, relation, p);
// 输入查询1
for(i=0;i<x;++i){
name1=sc.next();
System.out.println(queryFriendNum(name1, users, relation));
}
// 输入查询2
for(i=0;i<y;++i){
name1=sc.next();
name2=sc.next();
System.out.println(isFriend(name1, name2, users, relation));
}
}catch(Exception e){
}
}
}
遗憾的是recommend方法时间复杂度有点大,不知道有没有更好的方法?