2016年第七屆藍橋杯java B組省賽試題

2016年第七屆藍橋杯java B組省賽試題

  • 1-三、結果填空
  • 4-五、代碼填空
  • 6-七、結果填空
  • 8-十、程序設計

1.煤球數目  (結果填空)

有一堆煤球,堆成三角棱錐形。具體:
第一層放1個,
第二層3個(排列成三角形),
第三層6個(排列成三角形),
第四層10個(排列成三角形),
....
若是一共有100層,共有多少個煤球?
請填表示煤球總數目的數字。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。

示例代碼:java

public class Main1 {
    public static void main(String[] args) {
        int a[] = new int[101];
        for (int i = 1; i <= 100; i++) {
            a[i] = i * (i + 1) / 2;
        }
        int sum = 0;
      
        for (int i = 1; i <= 100; i++) {
            sum = sum + a[i];
        }
        System.out.println(sum);
    }
}

答案:c++

171700

二、生日蠟燭  (結果填空)

某君從某年開始每一年都舉辦一次生日party,而且每次都要吹熄與年齡相同根數的蠟燭。
如今算起來,他一共吹熄了236根蠟燭。
請問,他從多少歲開始過生日party的?請填寫他開始過生日party的年齡數。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。

答案:算法

26

參考代碼:編程

public class Main1 {
    public static void main(String[] args) {
        
        //i表明舉辦了i個生日party
        for (int startAge = 1; startAge < 1000; startAge++) {
            int sum = 0;
            for (int i = 0; i < 100; i++) {
                sum += startAge + i;
                if (sum == 236) {
                    System.out.println("startAge = " + startAge);
                }
            }
        }
    }
}

設:x爲開始過生日的年齡數,一共過了n個生日數組

Paste_Image.png

優化代碼,此時複雜度爲n;oop

public class Main {
    public static void main(String[] args) {
        for (int i = 1; i < 20; i++) {
            int isDivisible = (472+i-i*i) % (2*i);
            if (isDivisible==0){
                System.out.printf("年齡:"+(472+i-i*i) / (2*i));
                System.out.printf(",過了%d個生日\n", i);
            }
        }
    }
}

三、湊算式  (結果填空)

這個算式中A-I表明1-9的數字,不一樣的字母表明不一樣的數字。

好比:
6+8/3+952/714 就是一種解法,
5+3/1+972/486 是另外一種解法。
這個算式一共有多少種解法?
注意:你提交應該是個整數,不要填寫任何多餘的內容或說明性文字。優化

Paste_Image.png

import java.util.Stack;
/**
 * Created by harry on 2016/10/16.
 */

public class Main {
    public static int count = 0;
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        for (int a = 1; a < 10; a++) {
            stack.push(a);
            fun(stack);
            stack.pop();
        }
        System.out.println(count);
    }

    private static void fun(Stack<Integer> stack) {
        for (int j = 1; j < 10; j++) {
            if (stack.size() == 9) {
                int a = stack.get(0);
                int b = stack.get(1);
                int c = stack.get(2);
                int d = stack.get(3);
                int e = stack.get(4);
                int f = stack.get(5);
                int g = stack.get(6);
                int h = stack.get(7);
                int i = stack.get(8);
                int DEF = d * 100 + e * 10 + f;
                int GHI = g * 100 + h * 10 + i;
                int left = a * c * GHI + b * GHI + DEF * c;
                int right = 10 * c * GHI;
                if (left == right ) {
                    count++;
                }
                return;
            }
            if (!stack.contains(j)) {
                stack.push(j);
                fun(stack);
                stack.pop();
            }
        }
    }
}

答案編碼

29

四、 分小組  (代碼填空)

9名運動員參加比賽,須要分3組進行預賽。

有哪些分組的方案呢?spa

咱們標記運動員爲 A,B,C,... I設計

下面的程序列出了全部的分組方法。

該程序的正常輸出爲:

ABC DEF GHI

ABC DEG FHI

ABC DEH FGI

ABC DEI FGH

ABC DFG EHI

ABC DFH EGI

ABC DFI EGH

ABC DGH EFI

ABC DGI EFH

ABC DHI EFG

ABC EFG DHI

ABC EFH DGI

ABC EFI DGH

ABC EGH DFI

ABC EGI DFH

ABC EHI DFG

ABC FGH DEI

ABC FGI DEH

ABC FHI DEG

ABC GHI DEF

ABD CEF GHI

ABD CEG FHI

ABD CEH FGI

ABD CEI FGH

ABD CFG EHI

ABD CFH EGI

ABD CFI EGH

ABD CGH EFI

ABD CGI EFH

ABD CHI EFG

ABD EFG CHI

..... (如下省略,總共560行)。

參考示例:

public class A
{
    public static String remain(int[] a)
    {
        String s = "";
        for(int i=0; i<a.length; i++){
            if(a[i] == 0) s += (char)(i+'A');
        }
        return s;
    }

    public static void f(String s, int[] a)
    {
        for(int i=0; i<a.length; i++){
            if(a[i]==1) continue;
            a[i] = 1;
            for(int j=i+1; j<a.length; j++){
                if(a[j]==1) continue;
                a[j]=1;
                for(int k=j+1; k<a.length; k++){
                    if(a[k]==1) continue;
                    a[k]=1;
                   //此處應填 s+" "+(char)(i+'A')+(char)(j+'A')+(char)(k+'A')+" "+remain(a)  
                    System.out.println(__________________________________);  //填空位置  
                    a[k]=0;
                }
                a[j]=0;
            }
            a[i] = 0;
        }
    }

    public static void main(String[] args)
    {
        int[] a = new int[9];
        a[0] = 1;

        for(int b=1; b<a.length; b++){
            a[b] = 1;
            for(int c=b+1; c<a.length; c++){
                a[c] = 1;
                String s = "A" + (char)(b+'A') + (char)(c+'A');
                f(s,a);
                a[c] = 0;
            }
            a[b] = 0;
        }
    }
}

五、抽籤  (代碼填空)

X星球要派出一個5人組成的觀察團前往W星。

其中:

A國最多能夠派出4人。

B國最多能夠派出2人。

C國最多能夠派出2人。

....

那麼最終派往W星的觀察團會有多少種國別的不一樣組合呢?

下面的程序解決了這個問題。

數組a[] 中既是每一個國家能夠派出的最多的名額。

程序執行結果爲:

DEFFF

CEFFF

CDFFF

CDEFF

CCFFF

CCEFF

CCDFF

CCDEF

BEFFF

BDFFF

BDEFF

BCFFF

BCEFF

BCDFF

BCDEF

....

(如下省略,總共101行)

public class A {
    public static void f(int[] a, int k, int n, String s) {

        if (k == a.length) {
            if (n == 0) System.out.println(s);
            return;
        }

        String s2 = s;

        for (int i = 0; i <= a[k]; i++) {
            _________; //填空位置
          //應該填f(a,k+1,5-s2.length(),s2);
            s2 += (char) (k + 'A');
        }
    }

    public static void main(String[] args) {
        int[] a = {4, 2, 2, 1, 1, 3};
        f(a, 0, 5, "");
    }
}

六、方格填數(結果填空)

以下的10個格子

 +--+--+--+

         
       
     

(若是顯示有問題,也能夠參看【圖1.jpg】)

填入0~9的數字。要求:連續的兩個數字不能相鄰。
(左右、上下、對角都算相鄰)

一共有多少種可能的填數方案?

請填寫表示方案數目的整數。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。

 

package seven.six;

import java.util.Stack;
/**
 * A[2]reated on 2016/10/26 17:57
 *
 * @author harry
 * @version 1.0
 */
public class Test {
    public static int count = 0;
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        Stack<Integer> stack = new Stack<>();
        fun(stack);
        long endTime = System.currentTimeMillis();
        System.out.println("時間: " + (endTime - startTime));
        System.out.println("count=" + count);
    }

    private static void fun(Stack<Integer> stack) {
        if (stack.size() == 10) {
            int A[] = new int[10];
            A[0] = stack.get(0);
            A[1] = stack.get(1);
            A[2] = stack.get(2);
            A[3] = stack.get(3);
            A[4] = stack.get(4);
            A[5] = stack.get(5);
            A[6] = stack.get(6);
            A[7] = stack.get(7);
            A[8] = stack.get(8);
            A[9] = stack.get(9);
            boolean one = isNeibor(A[0], A[1], A[5], A[4], A[3]) && isNeibor(A[1], A[0], A[2], A[6], A[5], A[4]) && isNeibor(A[2], A[1], A[5], A[6]);
            boolean two = isNeibor(A[3], A[0], A[4], A[8], A[7]) && isNeibor(A[4], A[0], A[8], A[5], A[9], A[8], A[7], A[3])
                    && isNeibor(A[5], A[0], A[1], A[2], A[6], A[9], A[8], A[4]) && isNeibor(A[6], A[2], A[1], A[5], A[9]);
            boolean three = isNeibor(A[7],  A[8]) && isNeibor(A[8], A[9]);

            if (one && two && three) {
                System.out.printf("%d,%d,%d, %d,%d,%d,%d, %d,%d,%d\n", A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[8], A[9]);
                count++;
            }
            return;
        }
        for (int j = 0; j < 10; j++) {
            if (!stack.contains(j)) {
                stack.push(j);
                fun(stack);
                stack.pop();
            }
        }
    }

    public static  boolean isNeibor(int ...args){
        int first = args[0];
        for (int i = 1; i < args.length; i++) {
            if (Math.abs(first - args[i]) == 1) {
                return false;
            }
        }
        return true;
    }
}

答案

1580

七、剪郵票  (結果填空)

如【圖1.jpg】, 有12張連在一塊兒的12生肖的郵票。

如今你要從中剪下5張來,要求必須是連着的。

(僅僅鏈接一個角不算相連)

好比,【圖2.jpg】,【圖3.jpg】中,粉紅色所示部分就是合格的剪取。

請你計算,一共有多少種不一樣的剪取方法。

請填寫表示方案數目的整數。

注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。

$$ 圖1 $$

圖2

$$ 圖2 $$

$$ 圖3 $$

116

參考程序:

public class Main {
    private static int mp[] = {1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14};
    private static int aa[] = new int[5];
    private static int vis[] = new int[5];
    private static int sum = 0;
    private static int b[] = {-1, 1, -5, +5};

    public static void main(String[] args) {
        for (int a = 0; a < 12; a++)
            for (int b = a + 1; b < 12; b++)
                for (int c = b + 1; c < 12; c++)
                    for (int d = c + 1; d < 12; d++)
                        for (int e = d + 1; e < 12; e++) {
                            aa[0] = mp[a];
                            aa[1] = mp[b];
                            aa[2] = mp[c];
                            aa[3] = mp[d];
                            aa[4] = mp[e];
                            for (int i = 0; i < 5; i++) {
                                vis[i] = 0;
                            }
                            vis[0] = 1;
                            dfs(0);
                            int flag = 1;
                            for (int i = 0; i < 5; i++) {
                                if (vis[i] != 1) {
                                    flag = 0;
                                    break;
                                }
                            }
                            if (flag == 0) continue;
                            else{
                                sum++;
                            }
                        }
        System.out.println(sum);
    }

    public static void dfs(int n) {
        for (int i = 0; i < 4; i++) {
            int t = aa[n] + b[i];
            if (t < 1 || t > 14 || t == 5 || t == 10) continue;
            
            for (int j = 0; j < 5; j++)
                if (!(vis[j] == 1) && aa[j] == t) {
                    vis[j] = 1;
                    dfs(j);
                }
        }
    }
}

八、四平方和  (程序設計)

四平方和定理,又稱爲拉格朗日定理:

每一個正整數均可以表示爲至多4個正整數的平方和。
若是把0包括進去,就正好能夠表示爲4個數的平方和。

好比:
5 = 0^2 + 0^2 + 1^2 + 2^2
7 = 1^2 + 1^2 + 1^2 + 2^2
(^符號表示乘方的意思)

對於一個給定的正整數,可能存在多種平方和的表示法。
要求你對4個數排序:
0 <= a <= b <= c <= d
並對全部的可能表示法按 a,b,c,d 爲聯合主鍵升序排列,最後輸出第一個表示法

程序輸入爲一個正整數N (N<5000000)
要求輸出4個非負整數,按從小到大排序,中間用空格分開

例如,輸入:
5
則程序應該輸出:
0 0 1 2

再例如,輸入:
12
則程序應該輸出:
0 2 2 2

再例如,輸入:
773535
則程序應該輸出:
1 1 267 838

資源約定:
峯值內存消耗(含虛擬機) < 256M
CPU消耗  < 3000ms

請嚴格按要求輸出,不要多此一舉地打印相似:「請您輸入...」 的多餘內容。

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int Number = in.nextInt();
        int maxSubNumber = (int) Math.sqrt(Number);
        Loop:
        for (int a = 0; a <= maxSubNumber; a++) {
            for (int b = a; b < maxSubNumber; b++) {
                for (int c = b; c <= maxSubNumber; c++) {
                    for (int d = c; d <= maxSubNumber; d++) {
                        int S = a * a + b * b + c * c + d * d;
                        if (S == Number) {
                            System.out.print(a);
                            System.out.print(" " + b);
                            System.out.print(" " + c);
                            System.out.print(" " + d);
                            break Loop;
                        }
                    }
                }
            }
        }
    }
}

九、取球博弈  (程序設計)

兩我的玩取球的遊戲。

一共有N個球,每人輪流取球,每次可取集合{n1,n2,n3}中的任何一個數目。

若是沒法繼續取球,則遊戲結束。

此時,持有奇數個球的一方獲勝。

若是兩人都是奇數,則爲平局。

假設雙方都採用最聰明的取法,

第一個取球的人必定能贏嗎?

試編程解決這個問題。

輸入格式:

第一行3個正整數n1 n2 n3,空格分開,表示每次可取的數目 (0<n1,n2,n3<100)

第二行5個正整數x1 x2 ... x5,空格分開,表示5局的初始球數(0<xi<1000)

輸出格式:

一行5個字符,空格分開。分別表示每局先取球的人可否獲勝。

能獲勝則輸出+,

次之,若有辦法逼平對手,輸出0,

不管如何都會輸,則輸出-

例如,輸入:

1 2 3

1 2 3 4 5

程序應該輸出:

+ 0 + 0 -

再例如,輸入:

1 4 5

10 11 12 13 15

程序應該輸出:

0 - 0 + +

再例如,輸入:

2 3 5

7 8 9 10 11

程序應該輸出:

+ 0 0 0 0

資源約定:

峯值內存消耗(含虛擬機) < 256M

CPU消耗  < 3000ms

這一題比較難下手,咱們先來道題做爲引子

今盒子裏有n個小球,A、B兩人輪流從盒中取球,每一個人均可以看到另外一我的取了多少個,也能夠看到盒中還剩下多少個,而且兩人都很聰明,不會作出錯誤的判斷。

    咱們約定:
    每一個人從盒子中取出的球的數目必須是:1,3,7或者8個。

    輪到某一方取球時不能棄權!

    A先取球,而後雙方交替取球,直到取完。

    被迫拿到最後一個球的一方爲負方(輸方)
   

    請編程肯定出在雙方都不判斷失誤的狀況下,對於特定的初始球數,A是否能贏?

輸入
先是一個整數n(n<100),表示接下來有n個整數。而後是n個整數,每一個佔一行(整數<10000),表示初始球數。
輸出
程序則輸出n行,表示A的輸贏狀況(輸爲0,贏爲1)。
樣例輸入
4
1
2
10
18
樣例輸出
0
1
1
0

參考代碼:

import java.util.Scanner;

public class Test1 {//簡單博弈,找出必敗點必勝點
    static int b[] = {1, 3, 7, 8};
    static boolean a[] = new boolean[10010];

    public static void main(String[] args) {
        Init();
        Scanner input = new Scanner(System.in);
        int N = input.nextInt();
        while (N-- > 0) {
            int n = input.nextInt();
            System.out.println(a[n] ? 1 : 0);
        }
    }

    private static void Init() {
        for (int i = 1; i < 10000; i++) {//從1開始
            if (!a[i]) {
                for (int j = 0; j < 4; j++)
                    a[i + b[j]] = true;
            }
        }
    }
}

本題較難,本人暫時沒法找到解決方案!

十、壓縮變換(程序設計)

小明最近在研究壓縮算法。

他知道,壓縮的時候若是可以使得數值很小,就能經過熵編碼獲得較高的壓縮比。
然而,要使數值很小是一個挑戰。

最近,小明須要壓縮一些正整數的序列,這些序列的特色是,後面出現的數字很大多是剛出現過不久的數字。對於這種特殊的序列,小明準備對序列作一個變換來減少數字的值。

變換的過程以下:
從左到右枚舉序列,每枚舉到一個數字,若是這個數字沒有出現過,剛將數字變換成它的相反數,若是數字出現過,則看它在原序列中最後的一次出現後面(且在當前數前面)出現了幾種數字,用這個種類數替換原來的數字。

好比,序列(a1, a2, a3, a4, a5)=(1, 2, 2, 1, 2)在變換過程爲:
a1: 1未出現過,因此a1變爲-1;
a2: 2未出現過,因此a2變爲-2;
a3: 2出現過,最後一次爲原序列的a2,在a2後、a3前有0種數字,因此a3變爲0;
a4: 1出現過,最後一次爲原序列的a1,在a1後、a4前有1種數字,因此a4變爲1;
a5: 2出現過,最後一次爲原序列的a3,在a3後、a5前有1種數字,因此a5變爲1。
如今,給出原序列,請問,按這種變換規則變換後的序列是什麼。

輸入格式:
輸入第一行包含一個整數n,表示序列的長度。
第二行包含n個正整數,表示輸入序列。

輸出格式:
輸出一行,包含n個數,表示變換後的序列。

例如,輸入:
5
1 2 2 1 2

程序應該輸出:
-1 -2 0 1 1

再例如,輸入:
12
1 1 2 3 2 3 1 2 2 2 3 1

程序應該輸出:
-1 0 -2 -3 1 1 2 2 0 0 2 2

數據規模與約定
對於30%的數據,n<=1000;
對於50%的數據,n<=30000;
對於100%的數據,1 <=n<=100000,1<=ai<=10^9

資源約定:
峯值內存消耗(含虛擬機) < 256M
CPU消耗  < 3000ms

public class Test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int length = scanner.nextInt();
        int[] a = new int[length];

        for (int i = 0; i < length; i++) {
            a[i] = scanner.nextInt();
        }

        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < length; i++) {
            if (!map.keySet().contains(a[i])) {
                map.put(a[i], i);
                System.out.print(-a[i] + " ");
            } else {
                Integer position = map.get(a[i]);
                map.put(a[i], i);
                List<Integer> tmpList = new ArrayList<>();
                for (int j = position + 1; j < i; j++) {
                    if (!tmpList.contains(a[j])) {
                        tmpList.add(a[j]);
                    }
                }
                System.out.print(tmpList.size() + " ");
            }
        }
    }
}
相關文章
相關標籤/搜索