题目描述:
现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以它为中心的半径为实数Ri(0<Ri<15)的圆被湿润,这有充足的喷水装置i(1<i<600)个,并且一定能把草坪全部湿润,你要做的是:选择尽量少的喷水装置,把整个草坪的全部湿润。
输入:
第一行m表示有m组测试数据
每一组测试数据的第一行有一个整数数n,n表示共有n个喷水装置,随后的一行,有n个实数ri,ri表示该喷水装置能覆盖的圆的半径。
输出:
输出所用装置的个数
AC代码如下:
代码1
#include <stdio.h>
#include <math.h>
int main()
{
int i,n,j,k;
int count;
float ps[600],temp,wide,l;
scanf("%d",&n);
while(n--)
{
count=0;
wide=2,l=20;
scanf("%d",&i);
for(j=0;j<i;++j)
scanf("%f",&ps[j]);
for(j=0;j<i;++j)
if(ps[j]<1||ps[j]>=15)
return 0;
for(j=0;j<i-1;++j)
for(k=j+1;k<i;k++)
if(ps[j]<ps[k]) //冒泡排序
{
temp=ps[k];
ps[k]=ps[j];
ps[j]=temp;
}
for(j=0;j<i,l>=0;j++)
{
l=l-2*sqrt(ps[j]*ps[j]-(wide/2)*(wide/2));
count++;
}
printf("%d\n",count);
}
return 0;
}
代码2:
#include <stdio.h>
#include <iostream>
using namespace std;
#include <math.h>
int cmp (const void * a, const void * b)
{
return *(double *)b > *(double *)a ? 1 : -1;
}
int main()
{
int i,j=0,n,t;
double l,ps[600];
l=sqrt(20*20+2*2)/2;
scanf("%d",&n);
while(n--)
{
scanf("%d",&t);
for(i=0;i<t;i++)
scanf("%lf",ps+i);
qsort (ps, t, sizeof(ps[0]), cmp);
double count=0;
for(i=0;i<t;i++)
{
if(ps[i]<1||ps[i]>=15)
break;
count+=ps[i];
j++;
if(count>=l)
break;
}
printf("%d\n",j);
j=0;
}
return 0;
}
解题过程:刚接触到着这么个问题的时候,一头雾水。可是经过在本子上画图过后,思路立马浮现出来。这道题就是考查我们利用勾股定理,求解出整个矩形的对角线长,然后只要全部圆的半径之和大于这个矩形对角线就能保证将全部草坪湿润。有同学可能认为半径为1的不能覆盖这个宽为2的草坪,但是我们半径是可以累加和重叠的,因此半径为1的也符合要求。这里给出两段代码,希望大家自己在下面分析。
运行结果: