2013编程之美资格赛之树上的三角形(Java实现)

本文涉及的产品
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
简介: 树上的三角形 时间限制: 2000ms 内存限制: 256MB 描述 有一棵树,树上有只毛毛虫。它在这棵树上生活了很久,对它的构造了如指掌。所以它在树上从来都是走最短路,不会绕路。它还还特别喜欢三角形,所以当它在树上爬来爬去的时候总会在想,如果把刚才爬过的那几根树枝/树干锯下来,能不能从中选三根出来拼成一个三角形呢? 输入 输入数据的第一行包含一个整数 T,表示数据组数。 接下
树上的三角形


时间限制: 2000ms 内存限制: 256MB


描述
有一棵树,树上有只毛毛虫。它在这棵树上生活了很久,对它的构造了如指掌。所以它在树上从来都是走最短路,不会绕路。它还还特别喜欢三角形,所以当它在树上爬来爬去的时候总会在想,如果把刚才爬过的那几根树枝/树干锯下来,能不能从中选三根出来拼成一个三角形呢?


输入
输入数据的第一行包含一个整数 T,表示数据组数。


接下来有 T 组数据,每组数据中:


第一行包含一个整数 N,表示树上节点的个数(从 1 到 N 标号)。


接下来的 N-1 行包含三个整数 a, b, len,表示有一根长度为 len 的树枝/树干在节点 a 和节点 b 之间。


接下来一行包含一个整数 M,表示询问数。


接下来M行每行两个整数 S, T,表示毛毛虫从 S 爬行到了 T,询问这段路程中的树枝/树干是否能拼成三角形。


输出
对于每组数据,先输出一行"Case #X:",其中X为数据组数编号,从 1 开始。


接下来对于每个询问输出一行,包含"Yes"或“No”,表示是否可以拼成三角形。


数据范围
1 ≤ T ≤ 5


小数据:1 ≤ N ≤ 100, 1 ≤ M ≤ 100, 1 ≤ len ≤ 10000


大数据:1 ≤ N ≤ 100000, 1 ≤ M ≤ 100000, 1 ≤ len ≤ 1000000000


样例输入
2
5
1 2 5
1 3 20
2 4 30
4 5 15
2
3 4
3 5
5
1 4 32
2 3 100
3 5 45
4 5 60
2
1 4
1 3
样例输出
Case #1:
No
Yes
Case #2:
No
Yes


主要算法:
define results
get T
for 1 to T
get N
for 1 to N-1
get 边
getStruct 边s //构造类树
get M
define result
for 1 to M
get S,E
get S,E 到树根的路劲
get S,E 到树根的路劲的非公共节点
get S,E 间的路劲
get values S,E间路劲的段长度集合
sort(values)
result+=Test values //测试是否为三角形
results add result
print results


Test 算法
for i=2 to values.length
if values[i-2]+vaules[i-1]>values[i]
return true
return false


程序:


import java.util.*;

public class Main {

	public static void main(String[] args){
		
		Scanner sc=new Scanner(System.in);
		int T=sc.nextInt();
		
		String[] results=new String[T];
		for(int i=0;i<T;i++){
			int N=sc.nextInt();			
			int tempN=N-1;
			int[][] nodes=new int[tempN][3];
			for(int j=0;j<tempN;j++){
				nodes[j][0]=sc.nextInt();
				nodes[j][1]=sc.nextInt();
				nodes[j][2]=sc.nextInt();
			}
			List<ArrayList<Integer>> struct=getStruct(nodes);
			int M=sc.nextInt();
			String result="";
			for(int j=0;j<M;j++){
				int start=sc.nextInt();
				int end=sc.nextInt();
				result=result+" "+getResult(start,end,struct,nodes);
			}
			results[i]=result.trim();
		}
		
		printResult(results);
	}

	private static List<ArrayList<Integer>> getStruct(int[][] nodes) {
		ArrayList<Integer> num01s=new ArrayList<Integer>(nodes.length);
		int[] temp=new int[nodes.length+1];
		for(int i=0;i<temp.length;i++){
			temp[i]=0;
		}
		for(int i=0;i<nodes.length;i++){
			temp[(nodes[i][0]-1)]++;
			temp[(nodes[i][1]-1)]++;
		}
		for(int i=0;i<temp.length;i++){
			if(temp[i]==1)
				num01s.add(i+1);
		}
		int structLength=num01s.size()-1;
		List<ArrayList<Integer>> struct=new ArrayList<ArrayList<Integer>>(structLength);
		
		boolean[] flags=new boolean[structLength+1];
		for(int i=0;i<flags.length;i++){
			flags[i]=true;
		}
		List<Integer> success=new ArrayList<Integer>(nodes.length+1);
		for(int i=0;i<structLength;i++){
			ArrayList<Integer> list=new ArrayList<Integer>(nodes.length+1);
			for(int j=0;j<flags.length;j++){
				if(flags[j]){
					flags[j]=false;
					list.add(num01s.get(j));
					success.add(num01s.get(j));
					break;
				}
			}
			int node=list.get(0);
			boolean flag=true;
			while(flag){
				for(int k=0;k<nodes.length;k++){
					if((node==nodes[k][0])&&(!success.contains(nodes[k][1]))){
						list.add(nodes[k][1]);
						node=nodes[k][1];
						success.add(node);
						break;
					}else if((node==nodes[k][1])&&(!success.contains(nodes[k][0]))){
						list.add(nodes[k][0]);
						node=nodes[k][0];
						success.add(node);
						break;
					}
				}
				if(i!=0){
					int add=list.get(list.size()-1);
					for(int suc:success){
						for(int j=0;j<nodes.length;j++){
							if((suc==nodes[j][0] && add==nodes[j][1])||(suc==nodes[j][1] && add==nodes[j][0])){
								if(!list.contains(suc)){
									list.add(suc);
									flag=false;
									list=swap(list);
									break;
								}
							}
						}
					}
				}
				if(num01s.contains(node)){
					flags[num01s.indexOf(node)]=false;
					flag=false;
				}
			}
			struct.add(list);
		}
		return struct;
	}


	private static ArrayList<Integer> swap(ArrayList<Integer> list) {
		ArrayList<Integer> temp=new ArrayList<Integer>(list.size());
		for(int i=list.size()-1;i>=0;i--){
			temp.add(list.get(i));
		}
		return temp;
	}

	private static String getResult(int start, int end,
			List<ArrayList<Integer>> struct, int[][] nodes) {
		ArrayList<Integer> startPath=getNodePath(start,struct);
		ArrayList<Integer> endPath=getNodePath(end,struct);
		ArrayList<Integer> SE=new ArrayList<Integer>(nodes.length+1);
		int common=getCommonNode(startPath,endPath);
		if(startPath.indexOf(common)==0){
			SE=getPath(common,endPath);
		}else if( endPath.indexOf(common)==0){
			SE=getPath(common,startPath);
		}else {
			SE=getPath(common,startPath,endPath);
		}
		
		int[] values=getValue(SE,nodes);
		sort(values);
		return echo(values);
	}

	private static ArrayList<Integer> getPath(int common,
			ArrayList<Integer> list) {
		ArrayList<Integer> l=new ArrayList<Integer>(list.size());
		int n=list.indexOf(common);
		for(int i=0;i<=n;i++){
			l.add(list.get(i));
		}
		return l;
	}

	private static void sort(int[] values) {
		for(int i=0;i<values.length;i++){
			int min=i;
			for(int j=i+1;j<values.length;j++){
				if(values[j]<values[min])
					min=j;
			}
			if(i!=min){
				int temp=values[i];
				values[i]=values[min];
				values[min]=temp;
			}
		}
	}

	private static String echo(int[] values) {
		if(values.length<3)
			return "No";
		String result="No";
		for(int i=2;i<values.length;i++){
			if(judge(values[i-2],values[i-1],values[i])){
				result="Yes";
				break;
			}
		}
		return result;
	}

	private static boolean judge(int i, int j, int k) {
		return ((i+j)>k);
	}

	private static int[] getValue(ArrayList<Integer> sE,int[][] nodes) {
		int[] values=new int[sE.size()-1];
		for(int i=0;i<values.length;i++){
			for(int j=0;j<nodes.length;j++){
				int x=sE.get(i);
				int y=sE.get(i+1);
				if(nodes[j][0]==x && nodes[j][1]==y){
					values[i]=nodes[j][2];
					break;
				}else if (nodes[j][1]==x && nodes[j][0]==y){
					values[i]=nodes[j][2];
					break;
				}
			}
		}
		return values;
	}

	private static ArrayList<Integer> getPath(int m, 
			ArrayList<Integer> xList, ArrayList<Integer> yList) {
		ArrayList<Integer> path=new ArrayList<Integer>(xList.size()+yList.size());
		int xindex=xList.indexOf(m);
		int yindex=yList.indexOf(m);
		for(int i=0;i<xindex;i++){
			path.add(xList.get(i));
		}
		for(int i=yindex;i>=0;i--){
			path.add(yList.get(i));
		}
		return path;
	}

	private static int getCommonNode(ArrayList<Integer> xList,
			ArrayList<Integer> yList) {
		int max=xList.size();
		int c=-1;
		for(int i=0;i<max;i++){
			int temp=xList.get(i);
			if(yList.contains(temp)){
				c=temp;
				break;
			}
		}
		return c;
	}

	private static ArrayList<Integer> getNodePath(int start,
			List<ArrayList<Integer>> struct) {
		ArrayList<Integer> temp=new ArrayList<Integer>();
		temp.add(start);
		int s=start;
		int head=struct.get(0).get(0);
		int slength=struct.size();
		boolean flag=true;
		while(flag){
			for(int i=0;i<slength;i++){
				if(struct.get(i).contains(s) && s!=struct.get(i).get(0)){
					int x=struct.get(i).indexOf(s);
					
					for(int j=(x-1);j>=0;j--){
						temp.add(struct.get(i).get(j));
					}
					s=struct.get(i).get(0);
					break;
				}
			}
			if(head==s){
				flag=false;
			}
		}
		return temp;
	}

	private static void printResult(String[] result) {
		
		for(int i=0;i<result.length;i++){
		
			System.out.println("Case #"+(i+1)+":");
			
			String[] words=result[i].split(" ");
			for(String word:words)
				System.out.println(word);
		}
	}
}

这也是同样了,通过了比赛系统小数据测试,大数据测试未知。

——20130408



PS:

今天早晨数据出来了,这道题的大数据测试时TLE,超时。在情理之中。原因见博文《2013编程之美资格赛之大数据测试(Java实现)》

——20130409

相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps&nbsp;
相关文章
|
8天前
|
JSON Java Apache
非常实用的Http应用框架,杜绝Java Http 接口对接繁琐编程
UniHttp 是一个声明式的 HTTP 接口对接框架,帮助开发者快速对接第三方 HTTP 接口。通过 @HttpApi 注解定义接口,使用 @GetHttpInterface 和 @PostHttpInterface 等注解配置请求方法和参数。支持自定义代理逻辑、全局请求参数、错误处理和连接池配置,提高代码的内聚性和可读性。
|
10天前
|
安全 Java 编译器
JDK 10中的局部变量类型推断:Java编程的简化与革新
JDK 10引入的局部变量类型推断通过`var`关键字简化了代码编写,提高了可读性。编译器根据初始化表达式自动推断变量类型,减少了冗长的类型声明。虽然带来了诸多优点,但也有一些限制,如只能用于局部变量声明,并需立即初始化。这一特性使Java更接近动态类型语言,增强了灵活性和易用性。
92 53
|
9天前
|
存储 安全 Java
Java多线程编程的艺术:从基础到实践####
本文深入探讨了Java多线程编程的核心概念、应用场景及其实现方式,旨在帮助开发者理解并掌握多线程编程的基本技能。文章首先概述了多线程的重要性和常见挑战,随后详细介绍了Java中创建和管理线程的两种主要方式:继承Thread类与实现Runnable接口。通过实例代码,本文展示了如何正确启动、运行及同步线程,以及如何处理线程间的通信与协作问题。最后,文章总结了多线程编程的最佳实践,为读者在实际项目中应用多线程技术提供了宝贵的参考。 ####
|
6天前
|
监控 安全 Java
Java中的多线程编程:从入门到实践####
本文将深入浅出地探讨Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的摘要形式,本文将以一个简短的代码示例作为开篇,直接展示多线程的魅力,随后再详细解析其背后的原理与实现方式,旨在帮助读者快速理解并掌握Java多线程编程的基本技能。 ```java // 简单的多线程示例:创建两个线程,分别打印不同的消息 public class SimpleMultithreading { public static void main(String[] args) { Thread thread1 = new Thread(() -> System.out.prin
|
8天前
|
存储 缓存 安全
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见。本文介绍了使用 `File.createTempFile` 方法和自定义创建临时文件的两种方式,详细探讨了它们的使用场景和注意事项,包括数据缓存、文件上传下载和日志记录等。强调了清理临时文件、确保文件名唯一性和合理设置文件权限的重要性。
21 2
|
9天前
|
Java UED
Java中的多线程编程基础与实践
【10月更文挑战第35天】在Java的世界中,多线程是提升应用性能和响应性的利器。本文将深入浅出地介绍如何在Java中创建和管理线程,以及如何利用同步机制确保数据一致性。我们将从简单的“Hello, World!”线程示例出发,逐步探索线程池的高效使用,并讨论常见的多线程问题。无论你是Java新手还是希望深化理解,这篇文章都将为你打开多线程的大门。
|
10天前
|
安全 Java 编译器
Java多线程编程的陷阱与最佳实践####
【10月更文挑战第29天】 本文深入探讨了Java多线程编程中的常见陷阱,如竞态条件、死锁、内存一致性错误等,并通过实例分析揭示了这些陷阱的成因。同时,文章也分享了一系列最佳实践,包括使用volatile关键字、原子类、线程安全集合以及并发框架(如java.util.concurrent包下的工具类),帮助开发者有效避免多线程编程中的问题,提升应用的稳定性和性能。 ####
37 1
|
15天前
|
安全 Java 调度
Java中的多线程编程入门
【10月更文挑战第29天】在Java的世界中,多线程就像是一场精心编排的交响乐。每个线程都是乐团中的一个乐手,他们各自演奏着自己的部分,却又和谐地共同完成整场演出。本文将带你走进Java多线程的世界,让你从零基础到能够编写基本的多线程程序。
29 1
|
22天前
|
Java 数据处理 开发者
Java多线程编程的艺术:从入门到精通####
【10月更文挑战第21天】 本文将深入探讨Java多线程编程的核心概念,通过生动实例和实用技巧,引导读者从基础认知迈向高效并发编程的殿堂。我们将一起揭开线程管理的神秘面纱,掌握同步机制的精髓,并学习如何在实际项目中灵活运用这些知识,以提升应用性能与响应速度。 ####
43 3
|
23天前
|
Java
Java中的多线程编程:从入门到精通
本文将带你深入了解Java中的多线程编程。我们将从基础概念开始,逐步深入探讨线程的创建、启动、同步和通信等关键知识点。通过阅读本文,你将能够掌握Java多线程编程的基本技能,为进一步学习和应用打下坚实的基础。