认老乡-编程题有感

题目描述

大学的同学来自全国各地,对于远离家乡步入陌生大学校园的大一新生来说,碰到老乡是多么激动的一件事,于是大家都热衷于问身边的同学是否与自己同乡,来自新疆的小赛尤其热衷。但是大家都不告诉小赛他们来自哪里,只是说与谁同乡,从所给的信息中,你能告诉小赛有多少人确定是她的同乡吗?


输入

每个测试实例首先包括2个整数,N(1 <= N <= 1000),M(0 <= M <= N*(N-1)/2),代表现有N个人(用1~N编号)和M组关系;

在接下来的M行里,每行包括2个整数,a,b,代表a跟b是同乡;

当N = 0,M = 0输入结束;

已知1表示小赛本人。


输出

对于每个测试实例,输出一个整数,代表确定是小赛同乡的人数。


样例输入

3 1

2 3

5 4

1 2

3 4

2 5

3 2

0 0


样例输出

0

4

做这道题目时候也是一波三折,题目本身不难,但是需要注意的点有很多

(1)数据结构的选择,主要是关于集合的选择上

(2)题目条件的注意


代码1



import java.util.Scanner;
import java.util.*;
public class Main {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int M,N;	
		while(in.hasNext()){
			N=in.nextInt();
			M=in.nextInt();
			if(N==0 && M==0){
				break;
			}
			if(N<1 || N>1000 || M<0 || M>(N*(N-1)/2)){
				continue;
			}else{
				int[][] ralation = new int[1][2];
				HashMap> relationMap = new HashMap>();
				for (int i = 0; i < M; i++) {
					ralation[0][0]=in.nextInt();
					ralation[0][1]=in.nextInt();
					if(relationMap.get(ralation[0][0])==null){
						ArrayList list = new ArrayList();
						list.add(ralation[0][1]);
						relationMap.put(ralation[0][0], list);
					}else{
						relationMap.get(ralation[0][0]).add(ralation[0][1]);
					}
					if(relationMap.get(ralation[0][1])==null){
						ArrayList list = new ArrayList();
						list.add(ralation[0][0]);
						relationMap.put(ralation[0][1], list);
					}else{
						relationMap.get(ralation[0][1]).add(ralation[0][0]);
					}
				}

				if(relationMap.get(1)==null){
					System.out.println(0);
				}else{
					HashSet hasVisited = new HashSet();
					HashSet notVisited = new HashSet();
					notVisited.addAll(relationMap.get(1));
					while(notVisited.size()>0){
						int num = notVisited.iterator().next();
						notVisited.remove(num);
						hasVisited.add(num);
						if(relationMap.get(num)!=null){
							
								notVisited.addAll(relationMap.get(num));
								notVisited.removeAll(hasVisited);
						}
					}
					if(hasVisited.contains(1)){
						System.out.println(hasVisited.size()-1);
					}else{
						System.out.println(hasVisited.size());
					}
				}
			}	
		}
	}
}

代码2



import java.util.Scanner;
import java.util.*;
public class Main {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int M,N;	
		while(in.hasNext()){
			N=in.nextInt();
			M=in.nextInt();
			if(N==0 && M==0){
				break;
			}
			if(N<1 || N>1000 || M<0 || M>(N*(N-1)/2)){
				continue;
			}else{
				int[][] ralation = new int[1][2];
				HashMap> relationMap = new HashMap>();
				for (int i = 0; i < M; i++) {
					ralation[0][0]=in.nextInt();
					ralation[0][1]=in.nextInt();
					if(relationMap.get(ralation[0][0])==null){
						ArrayList list = new ArrayList();
						list.add(ralation[0][1]);
						relationMap.put(ralation[0][0], list);
					}else{
						relationMap.get(ralation[0][0]).add(ralation[0][1]);
					}
					if(relationMap.get(ralation[0][1])==null){
						ArrayList list = new ArrayList();
						list.add(ralation[0][0]);
						relationMap.put(ralation[0][1], list);
					}else{
						relationMap.get(ralation[0][1]).add(ralation[0][0]);
					}
				}

				if(relationMap.get(1)==null){
					System.out.println(0);
				}else{
					HashSet hasVisited = new HashSet();
					ArrayList notVisited = new ArrayList();
					notVisited.addAll(relationMap.get(1));
					while(notVisited.size()>0){
						int num = notVisited.remove(0);
						hasVisited.add(num);
						if(relationMap.get(num)!=null){
							for (int i = 0; i < relationMap.get(num).size(); i++) {
								if(!hasVisited.contains(relationMap.get(num).get(i))){
									notVisited.add(relationMap.get(num).get(i));
								}
							}
						}
					}
					if(hasVisited.contains(1)){
						System.out.println(hasVisited.size()-1);
					}else{
						System.out.println(hasVisited.size());
					}	
				}
			}	
		}
	}
}

代码1和代码2在后期数据处理的时候由于选用不同的数据结构,在效率上代码1明显高于代码2,这也是一个值得深思的问题,如何合理选用java提供的集合元素来满足程序功能的同时也达到高效的程序执行效果。代码2程序的执行时间在数据量大的时候会超时,代码1在这方面则比较有效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值