第六届蓝桥杯JavaB组解析(2015年)

1.三角形面积(水题)

/**
 * 1.三角形面积
 */
public class Main {
    public static void main(String[] args) {
        int area = (8*8) - (4*8)/2 - (4*6)/2 - (2*8)/2 ;
        System.out.println(area);
    }
}

2.立方变自身。

public class Main {
    static int count = 0 ;
    private static boolean f(int r, int i){
        String s = String.valueOf(r) ;
        int sum = 0 ;
        for(int j=0; j<s.length(); j++){
            sum += s.charAt(j) - '0' ;
        }
        if(sum == i){
            return true ;
        }
        return false ;
    }
    public static void main(String[] args) {
        for(int i=1;i<10000;i++){
            int r = i * i * i ;
            if(f(r,i)){
                count ++ ;
            }
        }
        System.out.println(count);
    }
}

3.三样献瑞

import java.util.Set;
import java.util.TreeSet;

/**
 * 根据已知公式:可以直接推出:
 * san = 1, yang = 0, xiang = 9, xian = 8 ;
 * 然后四层循环,用set去重,得到唯一的结果。
 */
public class Main1 {
    static int equation1 , equation2, result ;
    static Set<Integer> set ;
    static int san = 1, yang = 0, xiang = 9 , xian = 8 ;
    public static void main(String[] args) {
        set = new TreeSet<>() ;
            for(int rui=0; rui<=9; rui++) {
                for (int sheng = 0; sheng <= 9; sheng++) {
                    for (int hui = 0; hui <= 9; hui++) {
                        for (int qi = 0; qi <= 9; qi++) {
                            equation1 = xiang * 1000 + rui * 100 + sheng * 10 + hui;
                            equation2 = san * 1000 + yang * 100 + xian * 10 + rui;
                            result = san * 10000 + yang * 1000 + sheng * 100 + rui * 10 + qi;
                            if (result == equation1 + equation2) {
                                int [] temp = {san, yang, xian, rui, xiang, sheng, hui, qi} ;
                                for(int i=0; i<temp.length; i++) {
                                    set.add(temp[i]);
                                }
                                if(set.size() == 8) {
                                    System.out.println(san + "" + yang + "" + xian + "" + rui);
                                }else{
                                    set.clear();
                                }
                            }
                        }
                }
            }
        }
    }
}

4,5填空题略

6.加法变乘法

/**
 * 加法变乘法
 * 两个等式对应相减,把重复的去掉
 * 留下来的是i(i+1),j(j+1),(i+i+1),(j+j+1)
 */
public class Main {
    public static void main(String[] args) {
        for(int i=1; i<46; i++){
            for(int j=i+2; j<48; j++){
                if(i*(i+1) + j*(j+1) -(2*i+1) - (2*j+1)  == 2015 - 1225){
                    System.out.println(i + " " + j);
                }
            }
        }
    }
}

7.牌型种数

/**
 * 牌型种数:
 * 不考虑花色和自己得到牌的先后顺序,只考虑得到的点数
 * 也就是每张牌每次可以出现0~4次,一共13种数字的牌型,
 * 每次把13种牌型搜索一遍,并累积当前分配到牌的个数
 * 每次牌型都搜索一边且分配个数为13个,说明是一种方案
 */
public class Main {
    static int count = 0 ;
    private static void f(int level, int cnt){
        if(level>13 || cnt>13){
            return ;
        }
        if(level==13 && cnt==13){
            count ++ ;
        }
        for(int i=0; i<5; i++){
            f(level+1, cnt+i) ;
        }
    }
    public static void main(String[] args) {
        f(0, 0) ;
        System.out.println(count);
    }
}

8.饮料换购

import java.util.Scanner;

public class Main {
    static int n ;
    static int count = 0 ;
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in) ;
        n = input.nextInt() ;
        count = n ;
        while(n>=3){
            if(n % 3 == 0){
                count += (n/3) ;
                n = n / 3 ;
            }else{
                count += (n-(n%3)) / 3 ;
                n = (n%3) + ((n-(n%3)) / 3) ;
            }
        }
        System.out.println(count);
    }
}

9.垒骰子

import java.util.Scanner;

public class Main1 {
    static int n, m, count = 0;
    static int [] op = new int [7] ;
    static boolean [][] conflict = new boolean[7][7] ;
    static int [][] dp = new int [2][7] ;
    static int mod = 1000000007 ;
    private static void init(){
        op[1] = 4 ;
        op[2] = 5 ;
        op[3] = 6 ;
        op[4] = 1 ;
        op[5] = 2 ;
        op[6] = 3 ;
    }

    public static void main(String[] args) {
        init() ;
        Scanner input = new Scanner(System.in) ;
         n = input.nextInt() ;//骰子数
         m = input.nextInt() ; //m行
        for(int i=0; i<m; i++){
            int a = input.nextInt() ;
            int b = input.nextInt() ;
            conflict[a][b] = true ;
            conflict[b][a] = true ;
        }
        for(int i=1; i<=6; i++){
            dp[0][i] = 1 ;
        }
        int cur = 0 ;
        /**
         * 层数就是骰子数,也就是n,和6没有毛线关系,
         * 记住,记住,记住,level==n,
         * 测试用例的level是2,和6没有任何关系,
         * 王国栋,你长脑子了吗,认真思考,
         * 脚踏实地,欲带王冠,必受其重
         * 日拱一卒无有尽,功不唐娟终入海。
         */
            for(int level=2; level<=n; level++){
            cur = 1 - cur ;
            //尝试着把6个不同的面放在当前的骰子上
            for(int j=1;  j<=6; j++){
                dp[cur][j] = 0 ;
                for(int i=1; i<=6; i++){
                    if(conflict[op[i]][j]){
                        continue;
                    }
                    dp[cur][j] = (dp[cur][j] + dp[1-cur][i]) % mod ;
                }
            }
        }
        for(int i=1; i<=6; i++){
            count += dp[cur][i] ;
        }
        long ans = 1 ;
        long temp = 4 ;
        long p = n ;
        while(p != 0){
            if((p&1) == 1){
                ans = (ans * temp) ;
            }
            temp = (temp * temp) % mod ;
            p >>= 1 ;
        }
        System.out.println(count * ans);
    }
}

10.生命之树

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * 10.生命之树
 * 在X森林里,上帝创造了生命之树。
 *  * 他给每棵树的每个节点(叶子也称为一个节点)都标有一个整数,代表这个点的和谐值
 * 上帝要在这棵树中选择一个非空节点集S,使得对于S的任意两个节点a,b,都存在一个点列{a,v1,v2...vk,b}
 * 使得这个点列中的每个点都是S中的元素,且序列中相邻的两个点间有一条边相连,
 * 在这个前提下,上帝要使得S中的点所对应的整数和尽量最大,这个最大和就是上帝给生命之树的评分
 * 经过atm的努力,他已经知道了上帝给每棵树上每个节点的整数,但由于atm不擅长计算,
 * 他不知道怎么样有效的求评分,他需要你写一个程序计算每棵树的评分。
 *
 */
public class Main {
    static int n ;
    static long [] w ;
    static List<Integer>  [] g ; //数组作为List对象,用作邻接表
    static long ans ;
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in) ;
        n = input.nextInt() ; //n个节点
        w = new long [n+1] ;
        g = new ArrayList[n+1] ; //初始化对象数组,也需要初始化每一个对象
        initG() ; //初始化数组的每个对象
        for(int i=1; i<=n; i++){ //点的权重
            w[i] = input.nextInt() ;
        }
        for(int i=0; i<n-1; i++){ //n-1条边
            int a = input.nextInt() ;
            int b = input.nextInt() ;
            g[a].add(b) ;
            g[b].add(a) ;
        }
        dfs(1, 0) ;
        System.out.println(ans);
    }

    /**
     * U作为根所代表的子树有一个最大权和,将其存储到w[u]中
     * @param u
     * @param fa
     */
    private static void dfs(int u, int fa) {
        for(int i=0; i<g[u].size(); i++){
            Integer child = g[u].get(i) ;
            if(child == fa){
                continue ;
            }
            //以child为根所代表的子树有一个最大权和,将其存储到w[child]中
            dfs(child, u) ;
            if(w[child] > 0){
                w[u] += w[child] ;
            }
        }
        if(w[u] > ans){
            ans = w[u] ;
        }
    }

    private static void initG() {
        for(int i=0; i<n+1; i++){
            g[i] = new ArrayList<>() ;
        }
    }
}