一、横向打印二叉树
思路:既然是二叉树…那就很可能的要有新类point
先将输入的数存为数组,再将第一个元素当做root,节点整个结构的存储使用point[],每一个节点对应一个数组内的元素。第一个元素当做root,在第二个元素加入的时候,和root比较,如果值比root大,就存放在右边,比root小,就存放在左边。第三个元素加入的时候,先和root比较,如果比root大,且root右子树没有节点,就将第三个元素放在右子树上,如果右子树有元素,就将右子树暂作root,继续比较,直至找到一个空节点。、注意!在整个过程中,第一个元素一直是root,每给树加元素,就要从root开始~
源码来自:舞动的心
时间限制:1.0s 内存限制:256.0MB
问题描述
二叉树可以用于排序。其原理很简单:对于一个排序二叉树添加新节点时,先与根节点比较,若小则交给左子树继续处理,否则交给右子树。
当遇到空子树时,则把该节点放入那个位置。
比如,10 8 5 7 12 4 的输入顺序,应该建成二叉树如下图所示,其中.表示空白。
…|-12
10-|
…|-8-|
…|…|-7
…|-5-|
…|-4
本题目要求:根据已知的数字,建立排序二叉树,并在标准输出中横向打印该二叉树。
输入格式
输入数据为一行空格分开的N个整数。 N<100,每个数字不超过10000。
输入数据中没有重复的数字。
输出格式
输出该排序二叉树的横向表示。为了便于评卷程序比对空格的数目,请把空格用句点代替:
样例输入1
10 5 20
样例输出1
…|-20
10-|
…|-5
样例输入2
5 10 20 8 4 7
样例输出2
…|-20
…|-10-|
…|…|-8-|
…|…|-7
5-|
…|-4
package lijie_4;
import java.util.Scanner;
public class t_11_right {
public static int root;
public static point[] tree = new point[10005];
static class point {
public int value; //自身节点编号
public int father; //父母节点编号
public int left; //左孩子节点编号
public int right; //右孩子节点编号
public point() {
this.value = 0;
this.father = 0;
this.left = 0;
this.right = 0;
}
}
public void dfs(int start, String s, int n, String s1) {
if(tree[start].value == root)
s = s + tree[start].value;
else {
s = s + "-|-";
s = s + tree[start].value;
}
if(tree[start].right > 0) {
s1 = s1 + "1";
dfs(tree[start].right, s, n + 1, s1);
s1 = s1.substring(0, s1.length() - 1);
}
int len = s.length();
int cot = 0;
for(int i = 0;i < len;i++) {
if(s.charAt(i) == '|') {
if(s1.length() <= cot + 1 || s1.charAt(cot) != s1.charAt(cot + 1))
System.out.print("|");
else
System.out.print(".");
cot++;
} else if(cot < n) {
System.out.print(".");
} else {
System.out.print(s.charAt(i));
}
}
if(tree[start].left > 0 || tree[start].right > 0)
System.out.print("-|");
System.out.println();
if(tree[start].left > 0) {
s1 = s1 + "0";
dfs(tree[start].left, s, n + 1, s1);
s1 = s1.substring(0, s1.length() - 1);
}
}
public static void main(String[] args) {
t_11_right test = new t_11_right();
Scanner in = new Scanner(System.in);
String A = in.nextLine();
String[] arrayA = A.split(" ");
root = Integer.valueOf(arrayA[0]);
for(int i = 0;i < tree.length;i++)
tree[i] = new point();
for(int i = 0;i < arrayA.length;i++) {
int a = Integer.valueOf(arrayA[i]);
tree[a].value = a;
}
for(int i = 1;i < arrayA.length;i++) {
int a = Integer.valueOf(arrayA[i]);
int temp = root;
while(true) {
if(a > temp) {
if(tree[temp].right == 0) {
tree[temp].right = a;
break;
} else
temp = tree[temp].right;
}
else {
if(tree[temp].left == 0) {
tree[temp].left = a;
break;
} else
temp = tree[temp].left;
}
}
}
String s = "";
String s1 = "";
test.dfs(root, s, 0, s1);
}
}
二、危险系数(运行错误)
我的思路:从start开始dfs,一旦到end就把路径记录在某一static数组中。最后比对哪一个元素在每一个数组中都出现了
但是!我本地eclipse运行没错,提交之后 运行错误。我测了下时间,超时,2s。。。绝望… 正确代码在这里
时间限制:1.0s 内存限制:256.0MB
问题描述
抗日战争时期,冀中平原的地道战曾发挥重要作用。
地道的多个站点间有通道连接,形成了庞大的网络。但也有隐患,当敌人发现了某个站点后,其它站点间可能因此会失去联系。
我们来定义一个危险系数DF(x,y):
对于两个站点x和y (x != y), 如果能找到一个站点z,当z被敌人破坏后,x和y不连通,那么我们称z为关于x,y的关键点。相应的,对于任意一对站点x和y,危险系数DF(x,y)就表示为这两点之间的关键点个数。
本题的任务是:已知网络结构,求两站点之间的危险系数。
输入格式
输入数据第一行包含2个整数n(2 <= n <= 1000), m(0 <= m <= 2000),分别代表站点数,通道数;
接下来m行,每行两个整数 u,v (1 <= u, v <= n; u != v)代表一条通道;
最后1行,两个数u,v,代表询问两点之间的危险系数DF(u, v)。
输出格式
一个整数,如果询问的两点不连通则输出-1.
样例输入
7 6
1 3
2 3
3 4
3 5
4 5
5 6
1 6
样例输出
2
package lijie_4;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.TreeMap;
import java.util.Vector;
public class Main {
static ArrayList<Integer>[] als;//用于存放每一条正确道路的路径
static int len=0;
static boolean []vis;
public static void main(String[] args) {
int n,m;
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
m=sc.nextInt();
if(m!=0){
int [][]num=new int[m][2];
als=new ArrayList[m];
for(int i=0;i<m;i++){
for(int j=0;j<2;j++){
num[i][j]=sc.nextInt();
}
}
int u=sc.nextInt();
int v=sc.nextInt();
vis=new boolean[n];
ArrayList<Integer> ai=new ArrayList<Integer>();
Vector<Integer> vi=new Vector<Integer>();
long start=System.currentTimeMillis();
int t=demo(u,v,num,ai);
if(t==1){
System.out.println("-1");
}else{
TreeMap<Integer, Integer> tm=new TreeMap<Integer, Integer>();
for(int i=0;i<len;i++){
for(int j=0;j<als[i].size();j++){
if(tm.containsKey(als[i].get(j))){
if(als[i].get(j)!=v){
tm.put(als[i].get(j), tm.get(als[i].get(j))+1);
if( tm.get(als[i].get(j))==len){
vi.add(als[i].get(j));
}
}
}else{
if(als[i].get(j)!=v){
tm.put(als[i].get(j), 1);
}
}
}
}
System.out.println(vi.size());
}
long end=System.currentTimeMillis();
// System.out.println(end-start);
}else{
System.out.println("-1");
}
}
public static int demo(int start,int end,int [][]num,ArrayList<Integer> ai){
vis[start]=true;
if(start==end){
ArrayList<Integer> ait=new ArrayList<Integer>();
for(int i=0;i<ai.size();i++){
ait.add(ai.get(i));
}
als[len]=ait;
len++;
// System.out.println(als[len-1]);
return 0;
}
int flag=0;
for(int i=0;i<num.length;i++){
if(num[i][0]==start&&(!vis[num[i][1]])){
flag=1;
// System.out.println("0 "+num[i][1]);
ai.add(num[i][1]);
vis[num[i][1]]=true;
int t=demo(num[i][1],end,num,ai);
for(int j=0;j<ai.size()&&t!=1;j++){
if(ai.get(j)==num[i][1]){
// System.out.println("****"+ai.get(j)+" ");
ai.remove(j);
break;
}
}
vis[num[i][1]]=false;
}else if(num[i][1]==start&&(!vis[num[i][0]])){
flag=1;
// System.out.println("1 "+num[i][0]);
ai.add(num[i][0]);
vis[num[i][0]]=true;
int t=demo(num[i][0],end,num,ai);
for(int j=0;j<ai.size()&&(t!=1);j++){
if(ai.get(j)==num[i][1]){
// System.out.println("!!!"+ai.get(j)+" ");
ai.remove(j);
break;
}
}
vis[num[i][0]]=false;
}
}
if(flag==0){//证明该节点没有联通点了
for(int j=0;j<ai.size();j++){
if(ai.get(j)==start){
// System.out.println("~~~"+ai.get(j)+" ");
ai.remove(j);
break;
}
}
vis[start]=false;
return 1;
}
return 0;
}
}
三、零碎补充
java中用到的正则表达式