2016校招华为机试题——好友推荐

好友推荐

有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 
B C 
A C 



A B 
C A 
B C 
应输出: 





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方法时间复杂度有点大,不知道有没有更好的方法?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值