1. 程式人生 > >poj3301 Texas Trip (三分)

poj3301 Texas Trip (三分)

這個三分法對我來說是個比較陌生的東西,就在這裡總結一下

二分法適用於單調函式,但是對於單峰函式的解決,就只能用

三分法求解極值了。

對於三分法的話,給一個大神部落格的連結:

http://chenjianneng3.blog.163.com/blog/static/128345126201033101044920/

好了,轉到正題,這道題的題意是:求出能覆蓋一些點的正方形的面積的最小值

題意非常簡單,但思維難度有點大

乍一看題,感覺無從下手,就找了幾個例子來試驗,結果也沒研究出什麼名堂,就

只好去翻題解,看了題解,感覺恍然大悟,自己試驗的那幾個例子,都暗藏著這個

玄機。

首先,需要一個東西:對於平面上任意的一個點集,正方形邊長等於max(兩點之間的最大橫座標距離,兩點之間的最大縱座標距離)時

,該正方必能覆蓋這個點集。

對於上面那個玩意兒,應該是比較顯然的,然後呢,也可以看出這樣雖然可以找到一個滿足覆蓋點集的正方形,但是並不一定能夠保證面

積最小。好,精彩的地方來了:我們可以旋轉座標系,得到許多不同的正方形,面積最小的正方形必在其中。(這個也比較顯然,根據貪

心的思維,自然是越多點在正方形的邊上越好,所以面積最小的正方形一定有至少兩個點在它的邊上)

那麼旋轉座標系後,對於每個點,它的座標將有這樣的變化

(下面證明不充分,只證明了旋轉前旋轉後都在一象限的情況,後面的強行同理吧)

假設座標軸旋轉的角度為a,點的座標(x,y),點關於x軸的夾角為b

令t=sqrt(x*x+y*y)

那麼新的點的座標的表示式就是(t*cos(a+b),t*sin(a+b))

根據三角函式的公式,及cos b=x/t , sin b=y/t,展開可得:

座標為:(x*cos a-y*sin a ,x*sin a+y*cos a);

即 x'=x*cos a-y*sin a , y'=x*sin a+y*cos a

網上的好多篇文章都是推到了這一步,然後就什麼分析易得,正方形的

面積是一個下凸包啊,甚至直接上程式碼,表示懵比,這讓我這種渣渣這麼辦。。。

根據上面推出來的東西,正方形面積的表示式應該是

max( xmax - xmin ,ymax - ymin )^2

然後展開化標,再進行一堆三角變換,分情況討論,就能得到這是個下凸包了,不贅述

然後就是三分了,三分座標系的旋轉角度a (你得到的面積表示式的自變數)

程式碼:(精度要求好高的說,就因為精度wa了好多次)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>

const int MAXN=40;
const double pi=acos(-1.0);
const double esp=1e-12;
const double inf=1000;
using namespace std;
struct node{double x,y;}p[MAXN];
int T,N;

double lenth(double a){//!求座標系旋轉a時的正方形邊長
    double tx,ty,x1=-inf,y1=-inf,x2=inf,y2=inf;
    for(int i=1;i<=N;i++)
    {
        tx=p[i].x*cos(a)-p[i].y*sin(a);
        ty=p[i].x*sin(a)+p[i].y*cos(a);
        x1=max(tx,x1);  y1=max(ty,y1);
        x2=min(tx,x2);  y2=min(ty,y2);
    }
    return max(x1-x2,y1-y2);
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&N);
        for(int i=1;i<=N;i++)
        {
            scanf("%lf",&p[i].x);
            scanf("%lf",&p[i].y);
        }
        double l=0.0,r=pi,mid,midmid,ans=0.0;
        while(r-l>=esp)
        {
            mid=(l+r)*0.5;
            midmid=(mid+r)*0.5;
            ans=lenth(mid);
            if(ans<=lenth(midmid))
                r=midmid;
            else l=mid;
        }
        printf("%.2lf\n",ans*ans);
    }
    return 0;
}


相關推薦

poj3301 Texas Trip

這個三分法對我來說是個比較陌生的東西,就在這裡總結一下 二分法適用於單調函式,但是對於單峰函式的解決,就只能用 三分法求解極值了。 對於三分法的話,給一個大神部落格的連結: http://chenjianneng3.blog.163.com/blog/static/1283

[POJ3301]Texas Trip-最小正方形覆蓋

題目: 我是超連結 題解: 設正方形的邊都與座標軸平行可以求出來一個正方形 如果這個正方形旋轉一個角度的話正方形的大小可能會改變 經過我多年文化課做幾何旋轉題目,可以發現正方形的面積關於旋轉角度的函式單峰 如果面積隨角度變化是單峰的函式,那麼

poj3301--Texas Trip最小正方形覆蓋

題目大意:給出n個點的座標,現在要求一個正方形,完全包圍n個點,並且正方形面積最小,求最小的正方形面積。 表示不能理解為什麼面積隨著角度的變化是一個單峰的函式,等待大牛告訴一下,,, 如果面積隨角度

BZOJ3203 SDOI2013保護出題人

for 保護 維護 pan stdout line main sdoi2013 style   給a做一個前綴和,那麽現在每次所查詢的就是(sn-sk)/(bn+nd-(k+1)d)的最大值。這個式子可以看成是(bn+nd,sn)和((k+1)d,sk)所成直線的斜率。  

ACM_求第k大數

求第k大 Time Limit: 6000/3000ms (Java/Others) Problem Description: 給定兩個陣列A和B,大小為N,M,每次從兩個陣列各取一個數相乘放入陣列C,最終得到一個N*M的陣列C。求C中第K大的數。 Input: 輸入包含

TOJ3777 Function Problem

//三分 #include<iostream> #include<cstdio> #include<algorithm> #include<cmath&

#LOJ10013 曲線

題目連結 題目描述 明明做作業的時候遇到了 n 個二次函式 Si(x)=ax^2 + bx + c,他突發奇想設計了一個新的函式 F(x)=max⁡{Si(x)},i=1…n。 明明現在想求這個函式在 [0,1000] 的最小值,要求精確到小數點後四位,四捨五入。

hdu 5531 Rebuild

題目連結: 題目大意: 給出n個點,這n個點可以連成一個凸多邊形。現在以多邊形的端點作為圓心,分別做n個圓,要求在同一條線上的端點的圓是相切的。現在要求滿足條件以後,計算最小的圓面積總和。如果不能保證條件成立,則輸出impossible。 思路: 如果我們知道了第一個點上

poj 3737 UmBasketella

In recent days, people always design new things with multifunction. For instance, you can not only use cell phone to call your friends, but you can also u

HPUOJ 題目1079 假幣問題

1079: 假幣問題 時間限制: 1 Sec  記憶體限制: 128 MB提交: 7  解決: 1 [提交][狀態][討論版] 題目描述 居然有假幣!!!  事情是這樣的,現在豬肉漲了,但是農民的

HDU 5531 Rebuild——2015ACM/ICPC亞洲區長春站

傳送門 RebuildTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 2483    Accep

HDU 3400 Line belt

while freopen ios logs 三分 分享 -1 txt pri http://acm.split.hdu.edu.cn/showproblem.php?pid=3400 題意: 有兩條帶子ab和cd,在ab上的速度為p,在cd上的速度為q,在其它地方的速

POJ3977:Subset——題解+折半搜索

枚舉 cstring 不為 tdi bsp inline poj 折半 %d http://poj.org/problem?id=3977 題目大意:有一堆數,取出一些數,記他們和的絕對值為w,取的個數為n,求在w最小的情況下,n最小,並輸出w,n。 —&m

bzoj5164: 餐廳計劃問題+貪心

費用流 body play gpo return == while get tchar   網絡流經典題裏餐巾計劃的加強版...天數變成了$10^5$,那就不能用費用流做了...   考慮費用流的時候,單位費用隨流量的增加而減少,也就是說費用其實是個單峰(下凸)函數。

企業布式微服務雲SpringCloud SpringBoot mybatis 關於spring boot集成apidoc

用戶 osc height 註釋 success string 官方文檔 strong pass apidoc是基於註釋來生成文檔的,它不基於任何框架,而且支持大多數編程語言,為了springboot系列的完整性,所以標了個題。 一、apidoc簡介 apidoc通過在你代

#10013 曲線 法模板題

ase ext namespace lin str scrip sel nts otto 【題目描述】     明明做作業的時候遇到了 n 個二次函數 S?i??(x)=ax?2??+bx+c,他突發奇想設計了一個新的函數 F(x)=max{Si(x)},i=1…n。 明

章棧作業題2-棧及其應用-計算機17級 6-1 爆記憶體函式例項 6

6-1 爆記憶體函式例項 (6 分) 本題要求實現一個遞迴函式,使用者傳入非負整型引數n,使用者依次輸出1到n之間的整數。所謂遞迴函式就是指自己呼叫自己的函式。 說明: (1)遞迴函式求解問題的基本思想是把一個大規模問題的求解歸結為一個相對較小規模問題的求解, 小規模

章棧作業題2-棧及其應用-計算機17級 7-2 符號配對 20

7-2 符號配對 (20 分) 請編寫程式檢查C語言源程式中下列符號是否配對:/*與*/、(與)、[與]、{與}。 輸入格式: 輸入為一個C語言源程式。當讀到某一行中只有一個句點.和一個回車的時候,標誌著輸入結束。程式中需要檢查配對的符號不超過100個。 輸出

一道老坑爹的題章棧作業題2-棧及其應用-計算機17級 7-1 表示式轉換 25

 7-1 表示式轉換 (25 分) 算術表示式有字首表示法、中綴表示法和字尾表示法等形式。日常使用的算術表示式是採用中綴表示法,即二元運算子位於兩個運算數中間。請設計程式將中綴表示式轉換為字尾表示式。 輸入格式: 輸入在一行中給出不含空格的中綴表示式,可

章作業題3--佇列-計算機17級 7-1 銀行業務佇列簡單模擬 25

7-1 銀行業務佇列簡單模擬 (25 分) 設某銀行有A、B兩個業務視窗,且處理業務的速度不一樣,其中A視窗處理速度是B視窗的2倍 —— 即當A視窗每處理完2個顧客時,B視窗處理完1個顧客。給定到達銀行的顧客序列,請按業務完成的順序輸出顧客序列。假定不考慮顧客先後到達的時