BUPT2013计院机试Java题解

题目搜集于各位前辈,侵删。

第一题

日期
Description

请你计算出第X年Y月Z日是第X年的第几天。其中,1月1日是第一天,1月2日是第二天,以此类推。
计算时请注意闰年的影响。对于非整百年,年数能整除4是闰年,否则不是闰年;对于整百年,年数能整除400是闰年,否则不是闰年。如1900年和1901年不是闰年,而2000年和2004年是闰年。

InputFormat

第一行有一个整数T( T ≤ 100 T\leq100 T100),表示一共有T组数据需要你处理。
接下来一共有T行,每行是一个如下格式的字符串:X:Y:Z,表示你需要计算第X年Y月Z日是第X年的第几天。其中X是一个大于0,小于2100的整数。保证字符串的格式都是合法的,字符串所表示的日期也都是存在的。

OutputFormat

对于每组数据,你需要输出一个整数,表示所求得的结果。

SampleInput

2
2013:4:12
112:4:12

SampleOutput

102
103

import java.util.Scanner;

public class c1301 {

	static int[] days = {0,31,28,31,30,31,30,31,31,30,31,30,31};
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int T = sc.nextInt();
		for(int t=0;t<T;t++) {
			String s = sc.next();
			String[] ss = s.split(":");
			int year = Integer.parseInt(ss[0]);
			int month = Integer.parseInt(ss[1]);
			int day = Integer.parseInt(ss[2]);
			int sum = 0;
			for(int m = 1;m<month;m++) {
				sum+=days[m];
				if(m==2&&((year%4==0&&year%100!=0)||year%400==0)) {
					sum++;
				}
			}
			sum+=day;
			System.out.println(sum);
		}
		sc.close();
	}

}

第二题

统计节点个数
Description

给出一棵有向树,一共有N (1<N≤1000 )个节点,如果一个节点的度(入度+出度)不小于它所有儿子以及它父亲的度(如果存在父亲或儿子),那么我们称这个节点为p节点,现在你的任务是统计p节点的个数。

InputFormat

第一行为数据组数T (1≤T≤100 )。
每组数据第一行为N 表示树的节点数。后面为N−1 行,每行两个数x ,y (0≤x,y<N ),代表y 是x 的儿子节点。

OutputFormat

每组数据输出一行,为一个整数,代表这棵树上p节点的个数。

SampleInput

2
5
0 1
1 2
2 3
3 4
3
0 2
0 1

SampleOutput

3
1

Hint

第一组的p节点为1,2,3;第二组的p节点为0。

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class c1302 {

	static Node root = null;
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int T = sc.nextInt();
		for(int t=0;t<T;t++) {
			root = null;
			int n = sc.nextInt();
			for(int i = 0;i<n-1;i++) {
				int f = sc.nextInt();
				int s = sc.nextInt();
				if(root == null) {
					root = new Node(f);
					Node son = new Node(s);
					son.father = root;
					root.son.add(son);
				}else {
					Node father = search(f);
					Node son = new Node(s);
					son.father = father;
					father.son.add(son);
				}
			}
			int sum = 0;
			Queue<Node> q = new LinkedList<Node>();
			q.add(root);
			while(q.size()>0) {
				Node node = q.remove();
				int in = 0;
				int out =0;
				int fatherinout = 0;
				int soninout = 0;
				int flag = 0;
				
				if(node == root) {
					in = 0;
					fatherinout = 0;
				}else {
					in = 1;
					if(node.father == root) {
						fatherinout = node.father.son.size();
					}else {
						fatherinout = node.father.son.size()+1;
					}
				}
				
				out = node.son.size();	
								
				if(in+out<fatherinout) {
					flag = 1;
				}
				
				
				for(int i = 0;i<node.son.size();i++) {
					soninout = node.son.get(i).son.size()+1;
					if(in+out<soninout) {
						flag = 1;
						break;
					}
				}
				
				if(flag == 0) {
					sum++;	
				}
								
				for(int i = 0;i<node.son.size();i++) {
					q.add(node.son.get(i));
				}
				
			}
			
			System.out.println(sum);
		}
		sc.close();
	}

	static class Node{
		int value;
		Node father = null;
		ArrayList<Node> son = new ArrayList<Node>();
		public Node(int value) {
			super();
			this.value = value;
		}
	}
	
	static Node search(int value) {
		Queue<Node> q = new LinkedList<Node>();
		q.add(root);
		while(q.size()>0) {
			Node n = q.remove();
			if(n.value == value) {
				return n;
			}else {
				for(int i = 0;i<n.son.size();i++) {
					q.add(n.son.get(i));
				}
			}
		}
		return null;
	}
}

第三题

中序遍历序列
Description

给出一个序列,判断该序列是不是某二叉搜索树的中序遍历序列,如果是输出"Yes",否则输出"No"。

一颗带权二叉树是一颗二叉搜索树(二叉排序树),当且仅当对于任意一个节点,他的左子树中的所有权值小于当前节点的权值,且它的右子树中的所有权值均大于当前节点的权值。

Input Format

第一行T (T<=10 )代表数据组数。

每组数据包括两行:

第一行为一个整数N (1<=N<=400),表示序列的长度。

第二行包含N 个整数,表示这个这个序列,序列中的数的x 范围为(1<=x<=100000)。

OutPut Format

每组数据,如果是二叉搜索树的中序遍历序列输出"Yes",否则输出"No"。

Input

2
4
1 2 3 4
4
1 3 2 4

OutPut

Yes
No

import java.util.Scanner;

public class c1303 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int T = sc.nextInt();
		for(int t=0;t<T;t++) {
			int n = sc.nextInt();
			int pre = Integer.MIN_VALUE;
			int flag = 0;
			for(int i = 0;i<n;i++) {
				int a = sc.nextInt();
				if(a<pre) {
					flag = 1;
				}
				pre = a;
			}
			if(flag == 1) {
				System.out.println("No");
			}else {
				System.out.println("Yes");
			}
		}
		sc.close();
	}

}

第四题

最小距离查询
Description

给定一个由小写字母a到z组成的字符串S,其中第i个字符为S[i](下标从0开始)。你需要完成下面两个操作:

INSERT c

其中c是一个待输入的字符。你需要在字符串的末尾添加这个字符。保证输入的字符同样是a到z之间的一个小写字母。

QUERY x

其中x是一个输入的整数下标。对于这个询问,你需要回答在S当中和S[x]相等且与x最近的距离。输入保证x在当前字符串中合法。

例如S = “abcaba”,如果我们操作:
INSERT a

则在S的末端加一个字符a,S变成"abcabaa"。

接下来操作
QUERY 0

由于S[0] = a,在S中出现的离他最近的a在下标为3的位置上,距离为3 - 0 = 3。因此应当输出3。

接下来,如果
QUERY 4

S[4] = b,S中离它最近的b出现在下标为1处,距离为4 - 1 = 3。同样应当输出3。

给定初始字符串S和若干操作,对于每个QUERY,你需要求出相应的距离。

InputFormat

输入的第一行是一个正整数T (T≤20 ),表示测试数据的组数。

每组输入数据的第一行是一个初始串S。第二行是一个正整数m (1≤m≤100000 ),表示总共操作的数量。接下来m行,每行表示一个操作。操作的格式如上所述。

数据保证在任何情况下,S的长度不会超过100000。

OutputFormat

对于每个QUERY,输出所求的最小距离。如果S中其它位置都不存在和它相同的字符,输出-1。

SampleInput

2
axb
3
INSERT a
QUERY 0
QUERY 1
explore
3
INSERT r
QUERY 7
QUERY 1

SampleOutput

3
-1
2
-1

Hint

由于输入数据较大,C/C++中推荐使用scanf进行读入以获得更快的读入速度。同时请注意算法复杂度。

import java.util.Scanner;

public class c1304 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int T = sc.nextInt();
		for(int t=0;t<T;t++) {
			String s = sc.next();
			int n = sc.nextInt();
			for(int i = 0;i<n;i++) {
				String op = sc.next();
				if(op.equals("INSERT")) {
					String x = sc.next();
					s += x;	
				}else {
					int k = sc.nextInt();
					char c = s.charAt(k);
					int dis = Integer.MAX_VALUE;
					for(int j = 0;j<s.length();j++) {
						if(s.charAt(j)==c&&j!=k) {
							int temp = Math.abs(k-j);
							if(temp<dis) {
								dis = temp;
							}
						}
					}
					if(dis == Integer.MAX_VALUE) {
						System.out.println("-1");
					}else {
						System.out.println(dis);
					}
				}
			}
		}
		sc.close();
	}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值