1. 程式人生 > >Uva 4916 Selling Cells(隨機算法)

Uva 4916 Selling Cells(隨機算法)

cnblogs lin sqrt tro ace esp int 生成 個數

題意:

給定n個圓的 坐標 和半徑, 求第一個圓與其他圓相交的面積占第一個圓的面積的多大。

分析:

如果從局部去想, 處理每個圓之間的關系, 求出他們與第一個圓的交集, 這樣可能就會十分復雜了。

不妨從總體去想, 因為答案要求的數字並不是十分精確(保留兩位小數), 那麽我們可以試試隨機算法,

想象在第一個圓內撒綠豆, 那麽綠豆肯定會落到第一個圓與其他圓相交的區域, 這時候統計一下撒的綠豆和在區域中的綠豆就可以大概算出這個數字了。

這裏有個技巧是用

rand() /(double)(RAND_MAX/‘num‘)  生成 0 ~ num 的浮點數 rand()/(double)RAND_MAX 就是生成一個0 ~ 1的浮點數
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 25 + 7;
 4 int n;
 5 
 6 double x[maxn], y[maxn], r[maxn];
 7 
 8 double p2pdis(double x1, double y1, double x2, double y2){
 9     return sqrt((x1-x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
10 }
11 
12 int main(){
13     while
(scanf("%d", &n) && n){ 14 for(int i = 0; i < n; i++){ 15 scanf("%lf %lf %lf\n", &x[i], &y[i], &r[i]); 16 } 17 int time = 2e5;//設置最多循環次數, 在不超時的情況下設置的越大越好 18 int in = 0, tot = 0; 19 while(time--){ 20 double tx,ty; 21
tx = x[0] + rand() /(double)(RAND_MAX/ (-2 * r[0])) + r[0]; // 令tx在x的半徑內隨機 22 ty = y[0] + rand() /(double)(RAND_MAX/(-2 * r[0])) + r[0]; // 令ty在y的半徑內隨機 23 if(p2pdis(tx,ty,x[0],y[0]) < r[0]){//此時還要判斷一下這個點,是否在圓內, 因為我們是在以圓點為中心的正方形內取點 24 tot++;//判斷多少個點符合 25 for(int i = 1; i < n; i++){ 26 if(p2pdis(tx,ty,x[i],y[i]) <= r[i]){ 27 in++;//判斷多少個點在小圓內 28 break; 29 } 30 } 31 } 32 } 33 printf("%.2f\n",(double)in/tot); 34 } 35 }

Uva 4916 Selling Cells(隨機算法)