程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> UVa 10012 - How Big Is It?

UVa 10012 - How Big Is It?

編輯:C++入門知識

題目:給你m個圓,讓所有的圓都與底邊相切,求一個最小的矩形放下所有圓 。   分析:計算幾何、搜索。由於數據較小(8個)所以可以利用搜索枚舉所有狀態。然後求出其中最小的。   注意:每個圓不一定是與左邊相鄰的相切,如果用相鄰計算可能會覆蓋。這裡設第一個圓的切點坐標d[1] = (0,0),然後記錄所有切點坐標d[],每次尋找時枚舉所有左邊的圓找到相切的,求出對應的與平面的切點。最後沒舉出最大的d[i]+r[i]和d[i]-r[i]即可。   [cpp]  #include <stdio.h>   #include <stdlib.h>   #include <math.h>      double r[10];   int    u[10];   int    m[10];   int    p[40321][10];   int    Count;      //搜索求全排列    void dfs( int s, int n )    {       if ( s > n ) {           for ( int i = 1 ; i <= n ; ++ i )               p[Count][i] = m[i];           Count ++;           return;       }       for ( int i = 1 ; i <= n ; ++ i )           if ( !u[i] ) {               u[i] = 1;               m[s] = i;               dfs( s+1, n );               u[i] = 0;           }   }      int main()   {       int n,m;       while ( scanf("%d",&n) != EOF )        while ( n -- ) {           scanf("%d",&m);           double MinL = 0;           for ( int i = 1 ; i <= m ; ++ i ) {               scanf("%lf",&r[i]);               u[i] = 0;               MinL += 2.0*r[i];           }                      Count = 0;           dfs( 1, m );                      double a,b,c,d[10];           for ( int i = 0 ; i < Count ; ++ i ) {               for ( int j = 1 ; j <= m ; ++ j )                   d[j] = 0;                              //計算圓與底面切點                for ( int j = 2 ; j <= m ; ++ j ) {                   for ( int k = 1 ; k < j ; ++ k ) {                       a = r[p[i][j]]+r[p[i][k]];                       b = r[p[i][j]]-r[p[i][k]];                       c = d[k]+sqrt(a*a-b*b);                       if ( d[j] < c ) d[j] = c;                   }               }                              //枚舉端點找最值                double left = 0,righ = 0;               for ( int j = 1 ; j <= m ; ++ j ) {                   if ( left > d[j]-r[p[i][j]] )                        left = d[j]-r[p[i][j]];                   if ( righ < d[j]+r[p[i][j]] )                        righ = d[j]+r[p[i][j]];               }                              if ( MinL > righ-left ) MinL = righ-left;           }                      printf("%.3lf\n",MinL);       }       return 0;   }    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved