0
点赞
收藏
分享

微信扫一扫

历届试题 农场阳光

b91bff6ffdb5 2022-06-28 阅读 47

问题描述

  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 样例输入 20 10

45.0

2

5 0 5 5

8 6 14 6 样例输出 130.15 前言:这道题应该是难度很大的题,经过两小时的折腾之后,并在网上找答案的过程也证明了这道题的难度(目前没找到正确的代码),下面我的代码当精度给的很高的时候可以正确的求出答案,对于规模小的数据可以在1s内给出答案,但是测试数据一般都很刁钻,所以大部分的测试数据都是超时的。 当我把精度设小的时候,虽然大部分数据可以很快给出答案,但是答案只是接近正确的答案,所以下面的代码只是给出我的代码的思路,并没有正确的把这道题解决。 思路:因为题目的目的是求没有被云层遮挡的面积,而云层在地上留下的阴影是圆,那么我们求出每个云层在地上的圆心,并把整个土地划分很小的块(比如一平方米划分为100*100=10000份)(涉及到精度),计算每个块到各个圆的圆心的距离,如果这个距离都大于每个圆的半径,那么这个点就是没被遮挡的土地,否则就是被遮挡的, 计算没被遮挡的土地占所有的土地的百分比,进而计算出面积。 代码如下

1 #include<bits/stdc++.h>
2 using namespace std;
3
4 int main()
5 {
6 int a,b;
7 cin >> a >> b;
8 double g;
9 cin >> g;
10 g=g*3.1415926/180;//把角度化为弧度,因为计算机里面sin,cos的参数为弧度。
11 int n;
12 cin >> n;
13 int array[n][4];
14 memset(array,0,sizeof(array));
15 for(int i=0;i<n;i++){
16 cin >> array[i][0]>>array[i][1]>>array[i][2]>>array[i][3];
17 }
18 double array2[n][2];
19 memset(array2,0,sizeof(array2));
20 for(int i=0;i<n;i++){//求每个圆的圆心
21 array2[i][0]=array[i][0]+array[i][2]*(cos(g)/sin(g));
22 array2[i][1]=array[i][1];
23 }
24 int sum1=0;
25 int sum2=0;
26 int jingdu=200;//此时精度为200(即每一个单位在划分200份),精度越大,正确率越高,但是大的数据肯定超时。
27 for(int i=0;i<a*jingdu;i++){
28 for(int j=0;j<b*jingdu;j++){
29 int flag=0;
30 for(int k=0;k<n;k++){
31 double s=sqrt((i-array2[k][0]*jingdu)*(i-array2[k][0]*jingdu)+(j-array2[k][1]*jingdu)*(j-array2[k][1]*jingdu));
32 if(s<=array[k][3]*jingdu){//求出该点到每个阴影的距离并和半径做比较,在阴影内,标志位被修改。
33 flag=1;
34 break;
35 }
36
37 }
38 if(flag==0){
39 sum1++;//在阴影外的点
40 }else{
41 sum2++;
42 }
43 }
44 }
45 cout << sum1 << endl;
46 double so= sum1*1.0/(jingdu*jingdu);
47 cout << setiosflags(ios::fixed)<<setprecision(2) ;
48 cout << so;
49 return 0;
50 }

总之该代码可以在较短的时间内求出近似解(当jingdu比较小的时候),但是如果要求精确解,则参数jingdu越大越好,结果是大部分数据大大超时,也许某天计算机计算速度足够快,这个解法也许就不存在超时的问题了吧orz。

下面是蓝桥杯练习系统给的提示

 

 

 

历届试题 农场阳光_ios

 

 感觉就是在考数学,还没总结出规律。

有正确的解法或者思路的大佬请在下面留言。

**************************************************************************************************

后记

总结下代码里面两个小知识点

1:c++里面三角函数的参数是弧度,所以角度要换成弧度,公式为PI*角度/180

2:保留两位小数cout << setiosflags(ios::fixed)<<setprecision(2) ;

作者:你的雷哥

本文版权归作者所有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。

举报

相关推荐

0 条评论