本文目錄:oj題目 -> 分治法思路 -> 具體過程 -> tips -> 測試資料 -> **
這道題本身不是很難喲,不要被嚇到,然後就可以開始做了o(∩_∩)o~~
題目:
分治法思路:見
先預排序,預排序後最左和最右的點肯定是凸包中的點。然後可以遞迴的從內向外擴充套件凸包,在當前直線的2側尋找最高點,
最高點肯定在凸包中,這裡涉及到一些數學知識:
a,首先定義射線p1到p2的左側:若p1 p2 p構成的順序是逆時針,稱p在射線的左側
b,三角形p1 p2 p3的面積等於下列行列式的一半:
僅當p3在射線p1p2左側時這個值才為正。
由此我們很容易求p1,p2左側的最高點(離直線最遠的點,這個點即凸包向外擴充套件得到的新頂點),得到乙個最高點後,就得到了2條新邊,繼續向外擴充套件
那麼寫這個題的過程便可以是:
1.寫主函式,輸入
2.calsize函式,以最左右的兩點為引數(令為p1,p2)
3.編寫calsize函式,作用是呼叫callsize、calrsize函式,分別用來求p1p2直線上下的面積
4.編寫callsize、calrsize函式
5.寫callsize時,判斷方向,排除已經用掉的點,找到當前p點,根據求面積公式寫函式求△pp1p2面積,替換頂點遞迴
5.定義p1->p2->p[i]逆時針為左,反之為右,因為剛好判斷順逆時針的叉乘結果的絕對值等於三角形面積的兩倍,於是共用calarea(求面積)函式
tips:
判斷兩個平面向量構成的方向是順時針還是逆時針:
a = (ax,ay) , b = (bx,by)
a x b = ax * by - ay *bx
a x b > 0則是逆時針,< 0 則是順時針
已知三點座標求圍成三角形的面積(也是用叉乘,所以我寫在同乙個函式裡的,一起用):
ax = x1 - x2; ay = y1 - y2; bx = x2 - x3; by = y2 - y3;
a x b = ax * by - ay *bx
s = 0.5 * fabs((double)(a x b));//fabs為取絕對值,需要加上#include
改正:寫函式時如果呼叫在先定義在後,需要先宣告,再呼叫(宣告 != 呼叫)
改正:看是否符合公式使用條件,如fabs只用於浮點數
測試資料:(不包括資料組數t)
//正方形中間的點
50 0
2 00 2
2 21 1
//多組,記得初始化used
50 0
1 00 1
1 22 1
//比較的時候寫成if (x[j] > maxx)maxx = j;應該是x[j] > x[maxx],min也寫錯了
100 0
10 10
0 10
10 0
3 56 3
4 88 3
9 19 9
100 0
10 10
10 0
0 10
5 54 8
5 010 5
1 86 2
//答案0.0 1.0 0.5 6.041
184 225
40 0
0 11 0
1 13
0 00 1
1 06
0 21 1
0 02 1
3 03 2
**:
#include//分治法
#includeusing namespace std;
#includeint x[110],y[110],used[110]=;
double size;
double triangelsize(int i,int j,int k)
//定義:使得原兩點與新的點連線方向為逆時針的,為lside,即左,calarea>0則逆,《則順
double calarea(int p1,int p2,int i)
void callsize(int n,int p1,int p2)
}if (p == -1)return;
size += triangelsize(p1,p2,p);
callsize(n,p1,p);
callsize(n,p,p2);}
void calrsize(int n,int p1,int p2)
}if (p == -1)return;
size += triangelsize(p1,p2,p);
calrsize(n,p1,p);
calrsize(n,p,p2);}
void calsize(int n,int p1,int p2)
int main()
minx = maxx = x[0];
for(j = 0; j < n; j++)
calsize(n,minx,maxx);
printf("%.1lf\n",size);
}return 0;
}
written by sneexy
o(≧v≦)o~~ac了好興奮
swust oj 249 凸包面積
凸包面積 1000 ms 65535 kb 1078 3483 tags 分治法 麥兜是個淘氣的孩子。一天,他在玩鋼筆的時候把墨水灑在了白色的牆上。再過一會,麥兜媽就要回來了,麥兜為了不讓媽媽知道這件事情,就想用乙個白色的凸多邊形把牆上的墨點蓋住。你能告訴麥兜最小需要面積多大的凸多邊形才能把這些墨點...
swustoj凸包面積(分治法)
麥兜是個淘氣的孩子。一天,他在玩鋼筆的時候把墨水灑在了白色的牆上。再過一會,麥兜媽就要回來了,麥兜為了不讓媽媽知道這件事情,就想用乙個白色的凸多邊形把牆上的墨點蓋住。你能告訴麥兜最小需要面積多大的凸多邊形才能把這些墨點蓋住嗎?現在,給出了這些墨點的座標,請幫助麥兜計算出覆蓋這些墨點的最小凸多邊形的面...
swust OJ 249 求凸包面積模板
用graham scan 求出凸點,再用叉積求面積,乙個三角形的面積等於叉積的一半。define ios ios sync with stdio false cin.tie 0 cout.tie 0 include define int long long using namespace std t...