前幾天在某次比賽中遇到了這麼兩道題
第一道是求邊長爲1的正2n邊形的最小外接正方形的邊長,輸入的n都爲偶數
這個不難,因爲輸入的n爲偶數,所以這個正2n邊形邊的個數是能整除4的,而正方形恰好四條邊,所以最小的外接正方形只要像這樣正着放讓四個邊都貼着正方形就可以了
這裏就以這個正12邊形爲例,正12邊形的圖片是百度百科的然後自己畫了個正方形加了幾條輔助線。
這個就很好求了,正方形的邊長是2h,我們知道正2n邊形的邊長爲1,一半就是0.5,所以tan(a)=0.5/h,那麼只要求出角a就可以了,我們可以把正2n邊形切成2n個小等腰三角形,三角形的頂角就是2a,一圈是2π,一共2n個三角形,所以2a=2π/2n,化簡之後得出a=π/n/2,所以正方形邊長就等於2h=2×(0.5/tan(a))=1/tan(π/n/2),這個問題就解決了
代碼如下:
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int main()
{
int T;
cin >> T;
int n;
double PI = 3.141592653589793238;
while (T--)
{
scanf("%d", &n);
printf("%.9lf\n", 1 / tan(PI / 2 / n));
}
return 0;
}
然後另一道題和上一題其他條件都一樣,唯一不同的就是輸入的n都爲奇數
我好奇的用上一道題的代碼試了一下,雖然知道肯定不行,但就是想試
然後想知道n爲奇數的時候正2n邊形在最小的外接正方形裏是怎麼擺放的
因爲六邊形比較常見,研究的人應該挺多,所以就去百度了一下正六邊形的最小外接正方形
廢了好大力氣找到了正確的圖
我按照這個樣子嘗試着畫了一下正10的,但是手畫的實在是太醜了,然後就一時半會沒研究出來什麼規律,然後就去補學校的作業去了。
次日,研究了一會,無果
於是鼓起勇氣去問了大佬
爲了讓大佬看的方便,我忽然想到我可以百度搜圖然後用電腦畫一下
大概就是這樣,正2n邊形的一條對角線和正方形對角線重合。
在一番討論之後,得出了正解(大佬是真的強)
如圖所示:
可知正方形對角線的一半d的長度等於x的長度加y的長度
x=l×sin(a)(l也就是線段OC)
y=l×cos(a)
l很好求,由上一道題的圖可知,l=0.5/sin(π/n/2)
那麼角a怎麼求呢
如圖可知,將正2n邊形分成2n個小三角形後,三角形ABC所覆蓋的小三角形的個數爲n個,然後這n個小三角形又被線段OB分成數量差一的兩部分(隨着n的增大三角形越來越接近等腰直角三角形),然後因爲n是奇數所以這兩部分自然就是一個奇數一個偶數並且他們的差爲1(例如n=7時分成3和4,n=9時分成4和5,大概就是這個意思)
偶數的那部分的一半所佔的小三角形的頂角的和就是圖中的角a了
所以只要判斷一下n/2是奇數還是偶數,如果是偶數那角a所佔的小三角形份數就是n/4n/2如果是奇數那另一個偶數一定就是n/2+1,所以a佔的份數就是(n/2+1)/2
然後求出正方形對角線一半之後,把它乘根號2就是正方形的邊長了
代碼如下:
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int main()
{
int T;
cin >> T;
int n;
double PI = 3.141592653589793238;
double x, y, a, l;
while (T--)
{
scanf("%d", &n);
// 這裏用了一個三目判斷n/2是奇還是偶,然後求出a所佔的份數,進而求出a的度數
a = PI / n * ((n / 2) % 2 == 0 ? n / 4 : (n / 2 + 1) / 2);
// 然後求出l,x,y
l = 0.5 / sin(PI / n / 2);
x = l * sin(a);
y = l * cos(a);
// 然後x+y是對角線的一半,再乘根號2就是正方形邊長了
printf("%.9lf\n", (x + y) * sqrt(2));
}
return 0;
}
ヾ(≧∪≦*)ノ〃