2017年第八届蓝桥杯省赛Java B组真题+个人题解

目录

一、购物单

二、纸牌三角形

三、承压计算

七、日期问题

八、剪邮票

九、分巧克力

十、K倍区间


一、购物单

蓝桥杯官网_购物单

  思路:

一个一个输入计算总价格,计算出价格为5136.85···, 注意答案要求后两位是00,因此填5200

答案:

5200

输入数据:

180.90 0.88
10.25 0.65
56.14 0.9
104.65 0.9
100.30 0.88
297.15 0.5
26.75 0.65
130.62 0.5
240.28 0.58
270.62 0.8
115.87 0.88
247.34 0.95
73.21 0.9
101.00 0.5
79.54 0.5
278.44 0.7
199.26 0.5
12.97 0.9
166.30 0.78
125.50 0.58
84.98 0.9
113.35 0.68
166.57 0.5
42.56 0.9
81.9 0.95
131.78 0.8
255.89 0.78
109.17 0.9
146.69 0.68
139.33 0.65
141.16 0.78
154.74 0.8
59.42 0.8
85.44 0.68
293.70 0.88
261.79 0.65
11.30 0.88
268.27 0.58
128.29 0.88
251.03 0.8
208.39 0.75
128.88 0.75
62.06 0.9
225.87 0.75
12.89 0.75
34.28 0.75
62.16 0.58
129.12 0.5
218.37 0.5
289.69 0.8

代码:

import java.io.*;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static double nextDouble() throws IOException{
        st.nextToken();
        return st.nval;
    }
    static double x,y;
    public static void main(String args[]) throws IOException{
        double res=0;
        for(int i=0;i<50;i++){
            x=nextDouble();
            y=nextDouble();
            res+=x*y;
        }
        pw.println(res);
        pw.close();
    }
}


二、纸牌三角形

蓝桥杯官网_纸牌三角形

  思路:

给三角形的每个位置一个下标,1~9进行全排列,判断符合三条边相等的情况有多少种
(即a[1]+a[2]+a[3]+a[4]=a[4]+a[5]+a[6]+a[7]=a[7]+a[8]+a[9]+a[1])
注意旋转、镜像后相同算同一种,因此需要将答案除以6

 答案:

144

代码:

import java.io.IOException;
import java.io.PrintWriter;

public class Main{
    static PrintWriter pw=new PrintWriter(System.out);
    static int N=10;
    static int res=0;
    static int a[]=new int[N];
    static boolean flag[]=new boolean[N];
    public static boolean check(){
        int x=a[0]+a[1]+a[2]+a[3];
        int y=a[3]+a[4]+a[5]+a[6];
        int z=a[0]+a[6]+a[7]+a[8];
        if(x==y && y==z) return true;
        return false;
    }
    public static void dfs(int u){
        if(u==9){
            if(check()) res++;
            return;
        }
        for(int i=1;i<=9;i++){
            if(!flag[i]){
                flag[i]=true;
                a[u]=i;
                dfs(u+1);
                flag[i]=false;
            }
        }
    }
    public static void main(String args[]) throws IOException{
        dfs(0);
        pw.println(res/6);//旋转,镜像算一种,因此需要/6;
        pw.close();
    }
}

三、承压计算

蓝桥杯官网_承压计算

该官网题目出错了,原题中A~I代表1~9的数字而不是0~9的数字

 思路:

输入矩阵,然后遍历每个点,将该点重量的一半分均给左下方和右下方的数值,最后遍历最后一行的最大值max和最小值min,最小值显示为2086458231,则扩大的倍数为2086458231/min,给max扩大相同的倍数即可得到答案。

答案:

72665192664

代码:

import java.io.*;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    static int n;
    static double a[][]=new double[40][70];
    public static void main(String args[]) throws IOException{
        for(int i=1;i<=29;i++){
            for(int j=1;j<=i;j++){
                a[i][j]=nextInt();
            }
        }
        for(int i=1;i<=29;i++){
            for(int j=1;j<=i;j++){
                a[i+1][j]+=a[i][j]/2.0;
                a[i+1][j+1]+=a[i][j]/2.0;
            }
        }
        double max=-Double.MIN_VALUE;
        double min=Double.MAX_VALUE;
        for(int i=1;i<=30;i++){
            max= Math.max(max,a[30][i]);
            min= Math.min(min,a[30][i]);
        }
        pw.println(2086458231/min*max);
//        pw.println(72665192664l);
        pw.close();
    }
}

七、日期问题

蓝桥杯官网_日期问题

 思路:

枚举19600101到20591231中所有的数字,判断其中符合要求的有多少

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class Main{
    static BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter pw=new PrintWriter(System.out);
    static int days[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    public static boolean isleap(int year){
        return (year%400==0) || (year%4==0 && year%100!=0);
    }
    public static boolean check_valid(int year,int month,int day){
        if(month<1 || month>12) return false;
        if(day<1 || day>31) return false;
        if(month==2){
            if(isleap(year) && day>29) return false;
            if(!isleap(year) && day>28) return false;
        }
        else if(day>days[month]) return false;
        return true;
    }
    public static void main(String args[]) throws IOException{
        String s[]=bf.readLine().split("/");
        int a=Integer.parseInt(s[0]);
        int b=Integer.parseInt(s[1]);
        int c=Integer.parseInt(s[2]);
        for(int i=19600101;i<=20591231;i++){
            int year=i/10000;
            int month=i%10000/100;
            int day=i%100;
            if(check_valid(year,month,day)){
                if(year%100==a && month==b && day==c
                || year%100==c && month==a && day==b
                || year%100==c && month==b && day==a){
                    pw.printf("%d-%02d-%02d\n",year,month,day);
                }
            }
        }
        pw.close();
    }
}

八、剪邮票

蓝桥杯官网_包子凑数

 思路:

n,m两个数凑不出来的最大数为(n-1)*(m-1)=n*m-n-m
首先求所有a[i]的最大公约数,若不为1,则一定有无穷多个数凑不出来;
若为1,将每个数字看成一个物品,物品的体积即是该数字大小,每个物品有无穷多个,因此可将该问题转化为完全背包问题,最后判断有多少数字凑不出来即可

 代码:

import java.io.*;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    static int n;
    static int N=110;
    static int M=9710;//凑不出来的最大值为99*100-99-100=9702,因此9702后面的所有数字都可凑出
    static int a[]=new int[N];
    static boolean f[][]=new boolean[N][M];
    public static int gcd(int a,int b){
        return b==0?a:gcd(b,a%b);
    }
    public static void main(String args[]) throws IOException{
        n=nextInt();
        int d=0;
        for(int i=1;i<=n;i++){
            a[i]=nextInt();
            d=gcd(d,a[i]);
        }
        if(d!=1) pw.println("INF");
        else{
            f[0][0]=true;//初始化
            for(int i=1;i<=n;i++){
                for(int j=0;j<M;j++){
                    f[i][j]=f[i-1][j];
                    if(j>=a[i]) f[i][j]|=f[i][j-a[i]];
                }
            }
            int res=0;
            for(int i=0;i<M;i++) if(!f[n][i]) res++;
            pw.println(res);
        }
        pw.close();
    }
}

九、分巧克力

蓝桥杯官网_分巧克力

 思路:

二分巧克力的边长,check(x)函数判断边长为x时,切出来的巧克力数量是否大于等于k

代码:

import java.io.*;

public class Main{
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    static int n,k;
    static int N=100010;
    static int h[]=new int[N];
    static int w[]=new int[N];
    public static boolean check(int mid){
        int res=0;
        for(int i=1;i<=n;i++){
            res+=(w[i]/mid)*(h[i]/mid);
        }
        if(res>=k) return true;
        return false;
    }
    public static void main(String args[]) throws IOException{
        n=nextInt();
        k=nextInt();
        for(int i=1;i<=n;i++){
            h[i]=nextInt();
            w[i]=nextInt();
        }
        int l=1,r=(int)1e5;
        while (l<r){
            int mid=l+r+1>>1;
            if(check(mid)) l=mid;
            else r=mid-1;
        }
        pw.println(r);
        pw.close();
    }
}

十、K倍区间

蓝桥杯官网_K倍区间

 思路:

维护一个前缀和数组,当两个前缀和与k同余时,代表这两数之间为一个k倍区间

 代码:

import java.io.*;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    static int n,k;
    static int N=100010;
    static long a[]=new long[N];//前缀和数组,有可能爆int
    static int cnt[]=new int[N];//cnt[i]表示余数为i的个数
    public static void main(String args[]) throws IOException{
        n=nextInt();
        k=nextInt();
        for(int i=1;i<=n;i++){
            a[i]=nextInt();
            a[i]+=a[i-1];
        }
        cnt[0]=1;//表示余数为0,该前缀和自己就是一个答案,初始化为1
        long res=0;
        for(int i=1;i<=n;i++){
            res+=cnt[(int)(a[i]%k)];
            cnt[(int)(a[i]%k)]++;
        }
        pw.println(res);
        pw.close();
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值