題目描述:
現有一塊草坪,長爲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的也符合要求。這裏給出兩段代碼,希望大家自己在下面分析。運行結果: