關於尤拉公式在ACM中的應用
阿新 • • 發佈:2019-01-31
題目描述:你有一塊橢圓的地,你可以在邊界上選n個點,並兩兩連線得到n(n-1)/2條線段。他們最多能把土地分成多少個部分?
輸入:輸入包含多組測試資料,每組測試資料佔一行,代表在橢圓邊界選擇點的數量n(n>=2)。
輸出:輸出為多行,每組輸出佔一行,對於每組測試資料,輸出最多能把土地分成區域的數量。
樣例輸入:2
4
6
樣例輸出:2
8
31
提示:尤拉公式。
對於本題,利用尤拉公式求解。
在平面歐裡幾何中,尤拉公式簡寫成:V-E+F=2,其中V為平面中頂點的數量(包含頂點和所有交點),E為平面中邊的數量(包含所有的線段或線段弧),F為平面中所分割槽域的總數量(包含圖形中被分的和外側中無限大的平面)。
在本題中,我們不考慮外側的無限平面,那麼即得:V-E+F=1,換句話說,只要知道V和E的值,我們就可以求出F=E-V+1。
問題轉化為求E和V的值。
為了求出E和V的值,我們不得不對橢圓上的點進行列舉。實際上只要我們任意找兩個定點,這條線段就定了。而對於每條線段,兩側其他點的分佈方式是不一樣的。所以實際上列舉的是所選線段的左側有的點數,記為i,那麼右側一定有n-i-2個點。對於兩側每兩個點都有且僅有唯一的一條線段與之對應,切都會與所選線段交於一點。由於題目中求最優解,故任意三條線段交於一點的情況不考慮。這樣共可形成 i*(n-i-2)個交點,在所選線段上也會形成i*(n-i-2)個交點,而這些點將這條線段分成i*(n-i-2)+1條線段。這樣列舉每個點都可能是固定的定點,所以最後結果要乘以n,而每個點也被枚舉了2次,每次都會將兩側的點列舉兩次,故最終結果應該是實際的4倍,故E的結果應除以2,V的結果應除以4。
所以可以得出如下結論
V=n + n/4 * SUM (i*(n-2-i))(0<=i<=n-2)
E=n + n/2 * SUM (i*(n-2-i)+1) (0<=i<=n-2)
這樣可以得到以下程式碼:
#include <iostream>
#include <cstdio>
int main()
{
int i,n,s=0;
while(scanf("%d",&n)!=EOF)
{
s=0;
for(i=0;i<n-1;i++)
{
s+=2*(i*(n-2-i)+1);
s-=i*(n-2-i);
}
printf("%d\n",s*n/4+1);
}
return 0;
}
輸入:輸入包含多組測試資料,每組測試資料佔一行,代表在橢圓邊界選擇點的數量n(n>=2)。
輸出:輸出為多行,每組輸出佔一行,對於每組測試資料,輸出最多能把土地分成區域的數量。
樣例輸入:2
4
6
樣例輸出:2
8
31
提示:尤拉公式。
對於本題,利用尤拉公式求解。
在平面歐裡幾何中,尤拉公式簡寫成:V-E+F=2,其中V為平面中頂點的數量(包含頂點和所有交點),E為平面中邊的數量(包含所有的線段或線段弧),F為平面中所分割槽域的總數量(包含圖形中被分的和外側中無限大的平面)。
在本題中,我們不考慮外側的無限平面,那麼即得:V-E+F=1,換句話說,只要知道V和E的值,我們就可以求出F=E-V+1。
問題轉化為求E和V的值。
為了求出E和V的值,我們不得不對橢圓上的點進行列舉。實際上只要我們任意找兩個定點,這條線段就定了。而對於每條線段,兩側其他點的分佈方式是不一樣的。所以實際上列舉的是所選線段的左側有的點數,記為i,那麼右側一定有n-i-2個點。對於兩側每兩個點都有且僅有唯一的一條線段與之對應,切都會與所選線段交於一點。由於題目中求最優解,故任意三條線段交於一點的情況不考慮。這樣共可形成 i*(n-i-2)個交點,在所選線段上也會形成i*(n-i-2)個交點,而這些點將這條線段分成i*(n-i-2)+1條線段。這樣列舉每個點都可能是固定的定點,所以最後結果要乘以n,而每個點也被枚舉了2次,每次都會將兩側的點列舉兩次,故最終結果應該是實際的4倍,故E的結果應除以2,V的結果應除以4。
所以可以得出如下結論
V=n + n/4 * SUM (i*(n-2-i))(0<=i<=n-2)
E=n + n/2 * SUM (i*(n-2-i)+1) (0<=i<=n-2)
這樣可以得到以下程式碼:
#include <iostream>
#include <cstdio>
int main()
{
int i,n,s=0;
while(scanf("%d",&n)!=EOF)
{
s=0;
for(i=0;i<n-1;i++)
{
s+=2*(i*(n-2-i)+1);
s-=i*(n-2-i);
}
printf("%d\n",s*n/4+1);
}
return 0;
}