2013年第四届蓝桥杯Java程序设计本科B组决赛 农场阳光(编程大题)

2013年第四届蓝桥杯Java程序设计本科B组决赛个人题解汇总:

https://blog.csdn.net/daixinliangwyx/article/details/89946814

 

第六题

标题:农场阳光

交题测试链接:http://lx.lanqiao.cn/problem.page?gpid=T39

X星球十分特殊,它的自转速度与公转速度相同,所以阳光总是以固定的角度照射。
最近,X星球为发展星际旅游业,把空间位置出租给Y国游客来晒太阳。每个租位是漂浮在空中的圆盘形彩云(圆盘与地面平行)。当然,这会遮挡住部分阳光,被遮挡的土地植物无法生长。
本题的任务是计算某个农场宜于作物生长的土地面积有多大。

输入格式

  输入数据的第一行包含两个整数a, b,表示某农场的长和宽分别是a和b,此时,该农场的范围是由坐标(0, 0, 0), (a, 0, 0), (a, b, 0), (0, b, 0)围成的矩形区域。
  第二行包含一个实数g,表示阳光照射的角度。简单起见,我们假设阳光光线是垂直于农场的宽的,此时正好和农场的长的夹角是g度,此时,空间中的一点(x, y, z)在地面的投影点应该是(x + z * ctg(g度), y, 0),其中ctg(g度)表示g度对应的余切值。
  第三行包含一个非负整数n,表示空中租位个数。
  接下来 n 行,描述每个租位。其中第i行包含4个整数xi, yi, zi, ri,表示第i个租位彩云的圆心在(xi, yi, zi)位置,圆半径为ri。

输出格式

  要求输出一个实数,四舍五入保留两位有效数字,表示农场里能长庄稼的土地的面积。

例如:
用户输入:
10 10
90.0
1
5 5 10 5
程序应该输出:
21.46

再例如:
用户输入:
8 8
90.0
1
4 4 10 5
程序应该输出:
1.81

样例3:
用户输入:
20 10
45.0
2
5 0 5 5
8 6 14 6
程序输出:
130.15


资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗  < 2000ms


请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。


太菜了,只能拿到10分,下面是10分思路:

题目意思就是说:地面是一个(0,0)到(a,b)的矩形平面,把一些圆通过光线照射投射到地面(投射点公式题目已经给出来了),圆投射到地面还是圆,也就是说,求在这些投射圆外的面积。可以先把每个投射圆的圆心算出来存好,然后将地面的单位区域划分成自定义的num个区域,如[0,a)总共有a个整数点,将其划分成更小的单位后,相当于放大了num倍即总共有a*num个整数点,如果某个点到所有投射圆圆心的距离都大于这个圆的半径,说明这个点是属于投射圆外的面积的,统计这样的点占所有点的比例,那么就是投射圆外的面积占全部面积的比例,就可以得到投射圆外的面积了。

注意:cgt(x)=1.0/tan(x),这里的x要是弧度,因此如果x是角度要转换成弧度x=角度*Math.PI/180。

10分代码:

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.util.*;

public class Main {
    public static InputReader in = new InputReader(new BufferedInputStream(System.in));
    public static PrintWriter out = new PrintWriter(System.out);
    public static int a, b, n, x, y, z, sum, num;
    public static ArrayList<Double> centerx = new ArrayList<>();
    public static ArrayList<Double> centery = new ArrayList<>();
    public static ArrayList<Double> r = new ArrayList<>();
    public static double jd;

    public static void main(String[] args) {
        a = in.nextInt();
        b = in.nextInt();
        jd = in.nextDouble();
        n = in.nextInt();
        for (int i = 0; i < n; i++) {
            x = in.nextInt();
            y = in.nextInt();
            z = in.nextInt();
            r.add(in.nextDouble());
            centerx.add(x+z*1.0/Math.tan(jd*Math.PI/180));
            centery.add(y*1.0);
        }
        sum = 0;
        num = 300;//也就是精度,太大了会超时,太小了精度不够又错误
        for (int i = 0; i < a*num; i++) {
            for (int j = 0; j < b*num; j++) {
                int k;
                for (k = 0; k < n; k++) {
                    if (Math.sqrt((i-centerx.get(k)*num)*(i-centerx.get(k)*num) + (j-centery.get(k)*num)*(j-centery.get(k)*num)) < r.get(k)*num) break;
                }
                if (k == n) sum++;
            }
        }
        DecimalFormat df = new DecimalFormat("0.00");
        out.println(df.format(sum*1.0/(num*num)));
        out.flush();
        out.close();
    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public String nextLine() {
            String str = null;
            try {
                str = reader.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public Double nextDouble() {
            return Double.parseDouble(next());
        }

        public BigInteger nextBigInteger() {
            return new BigInteger(next());
        }

        public BigDecimal nextBigDecimal() {
            return new BigDecimal(next());
        }

    }
}

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值