蓝桥java练习记录

java蓝桥练习

1.尺取法

题目描述:
在BaiDu搜索引擎里,如何提高搜索效率是研发人员为之奋斗的目标。现在,密码库里也有一段数字片段S(0<长度<=100,000),HQ想通过智能搜索得到包含关键字P(0<长度<=100,000)的某个数段长度,如果存在多个这样的数段,则选择长度最小的。例如,数字片段123456789,关键字为257.显然S本身就包含257,所以长度9是一个符合的数段,但是HQ从S中找到子串234567也包含关键字,并且无法找到更短的子串满足条件,因此返回结果6。PS:密码库里的数字片段可能包含“*”,表示这一位可以是(0~9)中任意1个,具体见案例2。
输入:
输入有多个测试案例,每个测试案例1行,包括两个字串。
第一个为数字片段S(0<长度<=100,000),第二个为关键字P(0<长度<=100,000)。
输出:
根据输入案例返回查找结果,如果不存在包含关键字的数字片段则返回0。
样例输入:
123456789 257
样例输出:
6
    import java.util.Arrays;
    import java.util.Scanner;

    public class Main {
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            while(in.hasNext()){
                String s = in.next();
                String Mod = in.next();
                int num[] = new int [201];
                int need = Mod.length();
                int n = s.length();
                Arrays.fill(num, 0);
                for(int i= 0 ;i < need ;i++){
                    char c = Mod.charAt(i);
                    num[c]++;
                }
                int l = 0,r = 0,any = 0;
                int ans = n + 1;
                int cnt[] = new int [201];
                Arrays.fill(cnt, 0);
                while(true){
                    while(r < n && any < need){
                        if(s.charAt(r) == '*'){
                            any++;
                            r++;
                        }else{
                            char c = s.charAt(r);
                            if(cnt[c] < num[c]){
                                need--;
                            }
                            cnt[c]++;
                            r++;
                        }
                    }
                    if(any < need)break;
                    ans = Math.min(ans,r-l);
                    if(s.charAt(l) == '*'){
                        any--;
                        l++;
                    }else{
                        char c = s.charAt(l);
                        if(num[c] > 0 && cnt[c] <= num[c])
                            need++;
                        cnt[c]--;
                        l++;
                    }
                }
                System.out.println(ans % (n+1));
            }
        }
    }
···

## 2.BFS
···
第150题 贝多芬的第九交响曲(10分)
 题目描述:
         也许不是所有人都知道贝多芬的“第九交响曲”,但是所有

人都一定知道《欢乐颂》这首歌,它就是来自于贝多芬第九交响曲《合

唱》的第四乐章,玄影游侠受朋友推荐听了这部交响曲,并且被这部交

响曲深深地打动。
         2012年的11日上午,在奥地利首都维也纳新年音乐会上,

音乐家们会演奏这首交响曲,他现在非常想去现场感受一下。但是他还

是学生,并没有很多积蓄。音乐会的举办方考虑到一些学生的实际情况

,他们专门安排了一个智力挑战赛,完成挑战赛的人将免费获得一张维

也纳音乐会的门票。
         挑战赛规则如下:
         现在在一块空的场地上会有一个大的二维棋盘,裁判会给你

指定初始位置及一座贝多芬雕像所处的位置,你开始时就站在裁判指定

的初始位置处,你的目标是跳到贝多芬雕像的位置。为了给比赛增加一

定的难度,你在棋盘上行走时,必须按照中国象棋中的马的走步方式来

走。玩过中国象棋的人都知道,马走“日”,象走“田”。最后,你只

需要告诉裁判最少多少步能到达贝多芬的雕像。如果根本就到不了贝多

芬的雕像处,你直接告诉裁判就可以了。
         玄影游侠站在棋盘的某一个位置,不知道该如何走,他知道

你们都学过程序设计,所以想请你们帮帮忙编一个程序来帮助他找到想

要到达贝多芬的雕像处所需要的最少的步数。
输入:
         每组测试数据可能有多组输入,对于每一组输入,
         输入的第一行包括一个整数N(1<=N<=100),代表棋盘的大小

是N*N。
         输入的第二行包括四个数start_x, start_y, end_x, end_y

(1 <= start_x,start_y,end_x,end_y <= N),分别代表你开始时的位

置的x坐标和y坐标以及贝多芬雕像的x坐标和y坐标。
输出:
         如果你能够到达贝多芬雕像的位置,请输出最少需要多少步

。
         如果不能到达,则输出-1。
样例输入:
3
1 1 3 2

样例输出:
1

提示:
         注意,棋盘并不是中国象棋的棋盘,你可以把它理解成N*N的

类似于五子棋的棋盘。
···
···java
    import java.util.LinkedList;
    import java.util.Scanner;

    public class Main {
        static boolean a[][] = new boolean [101][101];
        static int num;
        static int dir[][]={{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2}};  
        static int sx,sy,ex,ey;
        static int check(){
            LinkedList<Node> p = new LinkedList<Node>();
            Node tmp = new Node(sx,sy,0);
            Node q = new Node(0,0,0);
            p.add(tmp);
            a[sx][sy] = true;
            while(!p.isEmpty()){
                tmp = p.getFirst();
                p.removeFirst();
                for(int i = 0; i < 8;i++){
                    q.x = tmp.getx() + dir[i][0];
                    q.y = tmp.gety() + dir[i][1];

                    if(q.x > 0&&q.y <= num&&q.x<=num&&q.y>0&&!a[q.x][q.y])  {
                        q.step = tmp.gets() + 1;
                        a[q.x][q.y] = true;
                    }if(q.x==ex&&q.y==ey)  
                        return q.step;
                    else p.add(q);
                }
            }
            return -1;
        }
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            while(in.hasNextInt()){
                num  = in.nextInt();
                sx = in.nextInt();
                sy = in.nextInt();
                ex = in.nextInt();
                ey = in.nextInt();
                System.out.println(check());
            }
        }
    }

    class Node{
        int x,y,step;
        public Node(int x,int y,int step){
            this.x = x;
            this.y = y;
            this.step = step;
        }
        public int getx(){
            return this.x;
        }
        public int gety(){
            return this.y;
        }
        public int gets(){
            return this.step;
        }
    }
···
## 3.栈的简单应用
···
第151题 栈的压入、弹出序列(10分)
 题目描述:
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列45,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
输入:
每个测试案例包括3行:
第一行为1个整数n(1<=n<=100000),表示序列的长度。
第二行包含n个整数,表示栈的压入顺序。
第三行包含n个整数,表示栈的弹出顺序。
输出:
对应每个测试案例,如果第二个序列是第一个序列的弹出序列输出Yes,否则输出No。
样例输入:
5
1 2 3 4 5
4 5 3 2 1

样例输出:
Yes
    import java.util.Scanner;
    import java.util.Stack;

    public class Main {
        static int push[] = new int [100010];
        static int pop[] = new int [100010];
        static boolean check(){
            Stack<Integer>stack = new Stack<>();
            int pushindex = 0 ;
            int popindex  = 0;
            while(popindex < pop.length){
                while(pushindex < push.length && (stack.isEmpty()||stack.peek()!=pop[popindex])){
                    stack.push(push[pushindex++]);
                }
                if(stack.peek()==pop[popindex]){
                    stack.pop();
                    popindex++;
                }else {
                    return false;
                }
            }
            return true;

        }
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Scanner in = new Scanner(System.in);
            while(in.hasNextInt()){
                int n = in.nextInt();
                for(int i = 0 ;i < n;i++)push[i] = in.nextInt();
                for(int i = 0 ;i < n;i++)pop[i] = in.nextInt();
                System.out.println(check()?"Yes":"No");
            }
        }

    }

4.二叉树

第152题 二叉搜索树的后序遍历序列(10分)
 题目描述:
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
输入:
每个测试案例包括2行:
第一行为1个整数n(1<=n<=10000),表示数组的长度。
第二行包含n个整数,表示这个数组,数组中的数的范围是[0,100000000]。
输出:
对应每个测试案例,如果输入数组是某二叉搜索树的后序遍历的结果输出Yes,否则输出No。
样例输入:

4
7 4 6 5
样例输出:

No
    import java.util.Scanner;

    public class Main {
        static int a[] = new int[100010];
        static  boolean VerifySquenceOfBST(int[] sequence) {
            if (sequence==null||sequence.length==0) {
                return false;
            }
            return isPos(sequence, 0, sequence.length-1);
        }
        static  boolean isPos(int[] ary,int start,int end) {
            if (start>end) {
                return true;
            }
            int index = end-1;
            while (index>start&&ary[index]>ary[end]) {
                index--;
            }
            for (int i = start; i < index; i++) {
                if (ary[i]>ary[end]) {
                    return false;
                }
            }
            return isPos(ary, start, index)&&isPos(ary, index+1, end-1);

        }
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Scanner in = new Scanner(System.in);
            while(in.hasNextInt()){
                int n = in.nextInt();
                for(int i = 0;i < n;i++)a[i] = in.nextInt();
                boolean b = VerifySquenceOfBST(a);
                if(b)System.out.println("Yes");
                else System.out.println("No");
            }
        }

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值