第十屆藍橋杯b組java

第十屆藍橋杯b組java


ps : 歷屆藍橋杯b組的題解用c寫過了 , 嘗試用java寫一下。。
1.組隊:
作爲籃球隊教練,你需要從以下名單中選出1 號位至5 號位各一名球員,
組成球隊的首發陣容。
每位球員擔任1 號位至5 號位時的評分如下表所示。請你計算首發陣容1
號位至5 號位的評分之和最大可能是多少?
在這裏插入圖片描述
思路:手算即可,但是本人年紀大了,眼神不好,所以用dfs做的。
答案:490

package com.Test.Demo;

import java.util.Arrays;

public class OjTest {
    //20個人選五個 求最大值
    private static int ans=0;
    private static int[] book=new int[20];
    private static int[][] a=new int[][]{
            {97,90,0,0,0},
            {92,85,96,0,0},
            {0,0,0,0,93},
            {0,0,0,80,86},
            {89,83,97,0,0},
            {82,86,0,0,0},
            {0,0,0,87,90},
            {0,97,96,0,0},
            {0,0,89,0,0},
            {95,99,0,0,0},
            {0,0,96,97,0},
            {0,0,0,93,98},
            {94,91,0,0,0},
            {0,83,87,0,0},
            {0,0,98,97,98},
            {0,0,0,93,86},
            {98,83,99,98,81},
            {93,87,92,96,98},
            {0,0,0,89,92},
            {0,99,96,95,81}};

    public static void main(String[] args){
       Arrays.fill(book,-1);
       dfs(0);
       System.out.println(ans);
    }
    public static void dfs(int x) { //選了x個位置
        if(x==5){
            int sum=0;
            for(int i=0;i<20;i++){
                if(book[i]!=-1){
                    sum+=a[i][book[i]];
                }
            }
            if(sum>ans){
                ans=sum;
            }
            return ;
        }
        for(int i=0;i<20;i++){
            if(book[i]==-1){
                book[i]=x;
                dfs(x+1);
                book[i]=-1;
            }
        }
    }
}

2.不同的子串:
一個字符串的非空子串是指字符串中長度至少爲1 的連續的一段字符組成
的串。例如,字符串aaab 有非空子串a, b, aa, ab, aaa, aab, aaab,一共7 個。
注意在計算時,只算本質不同的串的個數。
請問,字符串0100110001010001 有多少個不同的非空子串?

這是一道結果填空的題,你只需要算出結果後提交即可。本題的結果爲一
個整數,在提交答案時只填寫這個整數,填寫多餘的內容將無法得分。

思路:利用截取字符串的方法,枚舉長度和起點 ,截得所有子串,將其加到Set集合中去重,最後輸出集合長度即可。
答案:100

代碼:

package com.Test.Demo.WuQiShuZu;


import java.util.HashSet;

public class OjTest02 {
    public static void main(String[] args){
        //0100110001010001
        String str="0100110001010001";
        HashSet<String> hashSet=new HashSet();
        for(int i=1;i<=16;i++){
            for(int j=0;j+i-1<=16;j++){
                String string = str.substring(j,j+i-1);
                hashSet.add(string);
            }
        }
        System.out.println(hashSet.size());
    }
}

3.數列求值:
給定數列1, 1, 1, 3, 5, 9, 17, …,從第4 項開始,每項都是前3 項的和。求
第20190324 項的最後4 位數字。

思路:類似於斐波那契 , 不過填空題我們不必考慮超時,所以不用矩陣快速冪 ,直接取模求即可。

答案:4659

代碼:

package com.Test.Demo.WuQiShuZu;

public class OjTest03 {
    public static void main(String[] args){
        /*給定數列1, 1, 1, 3, 5, 9, 17, …,從第4 項開始,每項都是前3 項的和。求
        第20190324 項的最後4 位數字。*/
        int f1=1,f2=1,f3=1,f4=3;
        for(int i=4;i<=20190324;i++){
             f4=(f1+f2+f3)%10000;
             f1=f2;
             f2=f3;
             f3=f4;
        }
        System.out.println(f4);
    }
}

4.數的分解:
把2019 分解成3 個各不相同的正整數之和,並且要求每個正整數都不包
含數字2 和4,一共有多少種不同的分解方法?
注意交換3 個整數的順序被視爲同一種方法,例如1000+1001+18 和
1001+1000+18 被視爲同一種。

答案:40785

思路:水

代碼:

package com.Test.Demo.WuQiShuZu;

public class OjTest04 {
    private static int ans=0;
    public static void main(String[] args){
        for(int i=1;i<=2019;i++){
            for(int j=i+1;j<=2019;j++){
                for(int k=j+1;k<=2019;k++){
                    if(i+j+k==2019&&ok(i)&&ok(j)&&ok(k)){
                        ans++;
                    }
                }
            }
        }
        System.out.println(ans);
    }
    public static boolean ok(int x){
        while(x!=0){
            int s=x%10;
            x/=10;
            if(s==2||s==4){
                return false;
            }
        }
        return true;
    }
}

5.迷宮:
下圖給出了一個迷宮的平面圖,其中標記爲1 的爲障礙,標記爲0 的爲可
以通行的地方。

				010000
				000100
				001001
				110000

迷宮的入口爲左上角,出口爲右下角,在迷宮中,只能從一個位置走到這
個它的上、下、左、右四個方向之一。
對於上面的迷宮,從入口開始,可以按DRRURRDDDR 的順序通過迷宮,
一共10 步。其中D、U、L、R 分別表示向下、向上、向左、向右走。

對於下面這個更復雜的迷宮(30 行50 列),請找出一種通過迷宮的方式,
其使用的步數最少,在步數最少的前提下,請找出字典序最小的一個作爲答案。
請注意在字典序中D<L<R<U。

01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000

這是一道結果填空的題,你只需要算出結果後提交即可。本題的結果爲一
個字符串,包含四種字母D、U、L、R,在提交答案時只填寫這個字符串,填寫多餘的內容將無法得分。

思路:最短路徑 ,bfs,記錄一下路徑信息即可 。
答案:DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR

代碼:

package com.Test.Demo.WuQiShuZu;

import java.util.LinkedList;
import java.util.Scanner;

public class OjTest05 { //D<L<R<U。 D、U、L、R 分別表示向下、向上、向左、向右走。
    private static int flag = 0;
    private static int[][] bb = new int[30][50];
    private static String[] aa =new String[30];
    private static int[][]  next = {{1,0},{0,-1},{0,1},{-1,0}};
    public static void main(String[] args) {
        LinkedList<LuJing> luJings =new LinkedList<>();
        Scanner scanner = new Scanner(System.in);
        for(int i=0;i<30;i++){
            aa[i]=scanner.next();
        }
        char[][] ch = new char[30][];
        for(int i=0;i<30;i++){
            ch[i]=aa[i].toCharArray();
        }
        LuJing temp = null;
        bb[0][0]=1;
        luJings.add(new LuJing(0,0,0,null));
        while(luJings.size()!=0){
            int x0=luJings.peek().x;
            int y0=luJings.peek().y;
            for(int i=0;i<4;i++){
                int tx=x0+next[i][0];
                int ty=y0+next[i][1];
                if(tx>=0&&tx<30&&ty>=0&&ty<50&&ch[tx][ty]!='1'&&bb[tx][ty]==0){
                    temp = new LuJing(tx,ty,i,luJings.peek());
                    luJings.add(temp);
                    bb[tx][ty]=1;
                }
                if(tx==29&&ty==49){
                    flag=1;
                    break;
                }
            }
            if(flag==1){
                break;
            }
            luJings.poll();
        }
        StringBuffer stringBuffer = new StringBuffer();
        while(temp.supe!=null){//D<L<R<U
            if(temp.sup==0){
                stringBuffer.append("D");
            }else if(temp.sup==1){
                stringBuffer.append("L");
            }else if(temp.sup==2){
                stringBuffer.append("R");
            }else{
                stringBuffer.append("U");
            }
            temp = temp.supe;
        }
        StringBuffer stringBuffer1=stringBuffer.reverse();
        System.out.print(stringBuffer1);
    }
}
class LuJing{
    int x;
    int y;
    int sup;
    LuJing supe;
    public LuJing() {
    }

    public LuJing(int x, int y, int sup, LuJing supe) {
        this.x = x;
        this.y = y;
        this.sup = sup;
        this.supe = supe;
    }
}

6.特別數的和:
小明對數位中含有2、0、1、9 的數字很感興趣(不包括前導0),在1 到
40 中這樣的數包括1、2、9、10 至32、39 和40,共28 個,他們的和是574。
請問,在1 到n 中,所有這樣的數的和是多少?

輸入:

輸入一行包含一個整數n。

輸出:

輸出一行,包含一個整數,表示滿足條件的數的和。

【樣例輸入】
40
【樣例輸出】
574

思路:水。。。

package com.Test.Demo.WuQiShuZu;

import java.util.Scanner;

public class OjTest06 {
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int s=0;
        for(int i=1;i<=n;i++){
            if(!ok(i)){
                s+=i;
            }
        }
        System.out.print(s);
    }
    public static boolean ok(int x){
        while(x!=0){
            int temp = x%10;
            x/=10;
            if(temp==2||temp==0||temp==1||temp==9){
                return false;
            }
        }
        return  true;
    }
}

7.外賣店優先級:
“飽了麼”外賣系統中維護着N 家外賣店,編號1 N。每家外賣店都有
一個優先級,初始時(0 時刻) 優先級都爲0。
每經過1 個時間單位,如果外賣店沒有訂單,則優先級會減少1,最低減
到0;而如果外賣店有訂單,則優先級不減反加,每有一單優先級加2。
如果某家外賣店某時刻優先級大於5,則會被系統加入優先緩存中;如果
優先級小於等於3,則會被清除出優先緩存。
給定T 時刻以內的M 條訂單信息,請你計算T 時刻時有多少外賣店在優
先緩存中。

【輸入格式】
第一行包含3 個整數N、M 和T。
以下M 行每行包含兩個整數ts 和id,表示ts 時刻編號id 的外賣店收到
一個訂單。
【輸出格式】
輸出一個整數代表答案。
【樣例輸入】
2 6 6
1 1
5 2
3 1
6 2
2 1
6 2

【樣例輸出】
1

【樣例解釋】
6 時刻時,1 號店優先級降到3,被移除出優先緩存;2 號店優先級升到6,
加入優先緩存。所以是有1 家店(2 號) 在優先緩存中。

思路:我們把每個店的信息和每個店的訂單信息存在一個Map集合裏面 其中Map集合key部分爲外賣店對象 value部分爲此店的訂單信息(存在一個List集合中) 對每個店的訂單時間進行排序 遍歷訂單 計算得出優先級

代碼:

package com.Test.Demo.WuQiShuZu;

import java.util.*;
 /*我們把每個店的信息和每個店的訂單信息存在一個Map集合裏面 其中Map集合key部分爲外賣店對象 value部分爲此店的訂單信息(存在一個List集合中)
 對每個店的訂單時間進行排序 遍歷訂單 計算得出優先級*/
public class OjTest07 {
    private static int n,m,t,y;
    private static int ans=0;
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        n = scanner.nextInt();
        m = scanner.nextInt();
        t = scanner.nextInt();
        TreeMap<Mai,ArrayList<Integer>> treeMap = new TreeMap<>();//將每個外賣店的訂單信息存在TreeMap中
        for(int i=0;i<m;i++){ //m個訂單信息
            int tt = scanner.nextInt(); //時間
            int id = scanner.nextInt(); //店鋪
            ArrayList arrayList = treeMap.get(new Mai(id));  //如果已經有了此店鋪 獲取list集合 將時間加到集合中
            if(arrayList!=null){
                arrayList.add(tt);
            }else{
                ArrayList arrayList1 =new ArrayList();
                arrayList1.add(tt);
                treeMap.put(new Mai(id),arrayList1);
            }
        }
        Set<Mai> set = treeMap.keySet(); //獲取所有的外賣店
        for(Mai temp:set){ //遍歷所有外賣店
            ArrayList<Integer> arrayList=treeMap.get(temp); //獲取每個外賣店對應的List集合
            Collections.sort(arrayList);  //對List按照時間排序
            Object[] ee = arrayList.toArray(); //將List集合轉變爲數組
            int one = 0; //上一個訂單時間點
            int you = 0; //優先級
            int len = ee.length;
            y+=ee.length;
            boolean flag = false; //是否在優先隊列
            for(int i=0;i<len;){ // i<3
                int j=i;
                while(j<len&&ee[j]==ee[i]){
                    j++;
                }
                you-=((int)ee[i]-one-1);
                if(you<=0){
                    you=0;
                }
                if(flag&&you<=3){
                    flag=false;
                }
                you+=(j-i)*2;
                if(you>5){
                    flag = true;
                }
                one = (int)ee[i];
                i=j;
            }
            if((int)ee[len-1]!=t){
                you-=(t-(int)ee[len-1]);
            }
            if(you<0){
                you=0;
            }
            if(flag&&you<=3){
                flag=false;
            }
            if(flag){
                ans++;
            }
        }
        scanner.close();
        System.out.print(ans);
    }
}
class Mai implements Comparable<Mai>{
    private int id;

    public Mai() {
    }

    public Mai(int id) {
        this.id = id;
    }

    @Override
    public int compareTo(Mai o) { //排序的依據根據店鋪的id
        return this.id-o.id;
    }

    @Override
    public boolean equals(Object o) {  //id相同的店認爲是同一個店
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Mai mai = (Mai) o;
        return id == mai.id;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

    @Override
    public String toString() {
        return "Mai{" +
                "id=" + id +
                '}';
    }
}

8.人物相關性分析
【問題描述】
小明正在分析一本小說中的人物相關性。他想知道在小說中Alice 和Bob
有多少次同時出現。
更準確的說,小明定義Alice 和Bob“同時出現”的意思是:在小說文本
中Alice 和Bob 之間不超過K 個字符。
例如以下文本:
This is a story about Alice and Bob. Alice wants to send a private message to Bob.
假設K = 20,則Alice 和Bob 同時出現了2 次,分別是”Alice and Bob”
和”Bob. Alice”。前者Alice 和Bob 之間有5 個字符,後者有2 個字符。
注意:

Alice 和Bob 是大小寫敏感的,alice 或bob 等並不計算在內。

Alice 和Bob 應爲單獨的單詞,前後可以有標點符號和空格,但是不能
有字母。例如Bobbi 並不算出現了Bob。

【輸入格式】
第一行包含一個整數K。
第二行包含一行字符串,只包含大小寫字母、標點符號和空格。長度不超
過1000000。
【輸出格式】
輸出一個整數,表示Alice 和Bob 同時出現的次數。
【樣例輸入】

20
This is a story about Alice and Bob. Alice wants to send a private message to Bob.

【樣例輸出】
2

思路:

代碼:截取字符串 , 獲得每個名字的首字母所處的位置 ,統計每個名字前面k個字符內另一個名字出現的次數即可。

package com.Test.Demo.WuQiShuZu;

/*import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;*/
import java.util.*;
public class OjTest08{
    private static String string;
    private static int ans=0;
    public static void main(String[] args){

        Scanner scanner = new Scanner(System.in);
        ArrayList<Integer> a = new ArrayList<>();
        ArrayList<Integer> b = new ArrayList<>();
        scanner.useDelimiter("\n");
        int k = scanner.nextInt();
        string = scanner.next();
        for(int i=0;i+5<=string.length();i++) { //獲取所有Alice和Bob單詞首字母的位置
            if ((i == 0 ||ok(i - 1  )) && ( i + 5 == string.length()|| ok(i + 5)) ) {
                if(string.substring(i, i + 5).equals("Alice")){
                    a.add(i);
                }
            }
        }
        for(int i=0;i+3<=string.length();i++){
            if ((i == 0 || ok(i - 1)) && ( i + 3 == string.length()|| ok(i + 3)) ) {
                if(string.substring(i, i + 3).equals("Bob")){
                    b.add(i);
                }
            }
        }
        for(int i=0;i<a.size();i++){
            int r = 0;
            int l = 0;
            while(r<b.size()&&a.get(i)>b.get(r)){
                r++;
            }
            while(l<r&&a.get(i)>b.get(l)+k+3){
                l++;
            }
            ans+=(r-l);
        }
        for(int i=0;i<b.size();i++){
            int r = 0;
            int l = 0;
            while(r<a.size()&&b.get(i)>a.get(r)){
                r++;
            }
            while(l<r&&b.get(i)>a.get(l)+k+5){
                l++;
            }
            ans+=(r-l);
        }
        System.out.print(ans);
    }
    public static boolean ok(int x){ //判斷制定索引處是否爲單詞 不是單詞返回true
        char ch = string.charAt(x);
        if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')){
            return false;
        }else{
            return true;
        }
    }
}

9.後綴表達式:
【問題描述】
給定N 個加號、M 個減號以及N + M + 1 個整數A1; A2; ; AN+M+1,小
明想知道在所有由這N 個加號、M 個減號以及N + M +1 個整數湊出的合法的
後綴表達式中,結果最大的是哪一個?
請你輸出這個最大的結果。
例如使用1 2 3 + -,則“2 3 + 1 -” 這個後綴表達式結果是4,是最大的。
【輸入格式】
第一行包含兩個整數N 和M。
第二行包含N + M + 1 個整數A1; A2; ; AN+M+1。
【輸出格式】
輸出一個整數,代表答案。
【樣例輸入】
1 1
1 2 3
【樣例輸出】
4

思路:特殊情況:m=0,直接輸出和
一般情況:把所有數排個序,最大的拿出來,放首項,把最小的數拿出來,給他一個減號,再套一個括號,那麼現在還未完成的表達式長這樣:

可以發現,現在如果我想加一個數的話,給它一個加號,放在括號外面,也可以給它一個減號,放在括號裏面;減一個數同理。換句話說,只要用一個減號,一個最大值,一個最小值,其他數我想加就加,想減就減。那麼爲了使結果最大,我加上正數,減去負數,就是直接加上所有剩下數的絕對值,那麼就解決了

代碼:

package com.Test.Demo.WuQiShuZu;

import java.util.*;

public class OjTest09 {
	public static void main(String[] args) {
		Scanner scanf = new Scanner(System.in);
		long n = scanf.nextLong();
		long m = scanf.nextLong();
		int k = (int)(n+m+1);
		long sum = 0;
		long ans = 0;
		long[] array = new long[k];
		for(int i=0;i<k;i++) {
			array[i] = scanf.nextInt();
			sum+=array[i];
		}
		if(m==0) {
			System.out.println(sum);
		}else {
			Arrays.sort(array);
			ans-=array[0];
			ans+=array[k-1];
			for(int i=1;i<array.length-1;i++) {
				ans+=Math.abs(array[i]);
			}
			System.out.println(ans);
		}
	}

}


水平有限,不足之處請指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章