小明和朋友們一起去郊外植樹,他們帶了一些在自己實驗室精心研究出的小樹苗。 小明和朋友們一共有 n 個人,他們經過精心挑選,在一塊空地上每個人挑選了一個適合植樹的位置,總共 n 個。他們準備把自己帶的樹苗都植下去。 然而,他們遇到了一個困難:有的樹苗比較大,而有的位置挨太近,導致兩棵樹植下去后會撞在一起。 他們將樹看成一個圓,圓心在他們找的位置上。如果兩棵樹對應的圓相交,這兩棵樹就不適合同時植下(相切不受影響),稱為兩棵樹沖突。 小明和朋友們決定先合計合計,只將其中的一部分樹植下去,保證沒有互相沖突的樹。他們同時希望這些樹所能覆蓋的面積和(圓面積和)最大。
輸入格式
輸入的第一行包含一個整數 n ,表示人數,即準備植樹的位置數。 接下來 n 行,每行三個整數 x, y, r,表示一棵樹在空地上的橫、縱坐標和半徑。
對于 30% 的評測用例,1 <= n <= 10; 對于 60% 的評測用例,1 <= n <= 20; 對于所有評測用例,1 <= n <= 30,0 <= x, y <= 1000,1 <= r <= 1000。
package 省模擬賽;import java.util.Scanner;publicclass 植樹2{publicstaticboolean[][] bool =newboolean[31][31];staticboolean[] vis =newboolean[31];publicstaticint[] x =newint[31];publicstaticint[] y =newint[31];publicstaticint[] r =newint[31];publicstaticint n =0, max =-1;publicstaticvoidmain(String[] args){Scanner sc =newScanner(System.in);n = sc.nextInt();for(int i =1; i <= n; i++){x[i]= sc.nextInt();y[i]= sc.nextInt();r[i]= sc.nextInt();}for(int i =1; i <= n; i++){for(int j = i +1; j <= n; j++){boolean bo =((x[i]- x[j])*(x[i]- x[j])+(y[i]- y[j])*(y[i]- y[j])>(r[i]+ r[j])*(r[i]+ r[j]));bool[i][j]= bo;bool[j][i]= bo;}}sc.close();dfs(1);System.out.println(max);}publicstaticvoiddfs(int step){if(step > n){int sum =0;for(int i =1; i <= n; i++){if(vis[i]){sum +=(r[i]* r[i]);}}max = Math.max(sum, max);return;}vis[step]=false;dfs(step +1);for(int i =1; i < step; i++){if(vis[i]&&!bool[i][step]){return;}}vis[step]=true;dfs(step +1);}}