HNOI 2012 射箭 半平面交

2021-07-15 14:51:51 字數 2085 閱讀 1806

description

沫沫最近在玩乙個二維的射箭遊戲,如下圖 1 所示,這個遊戲中的 x 軸在地面,第一象限中有一些豎直線段作為靶子,任意兩個靶子都沒有公共部分,也不會接觸座標軸。沫沫控制乙個位於(0,0)的弓箭手,可以朝 0 至 90?中的任意角度(不包括 0度和 90度),以任意大小的力量射出帶有穿透能力的光之箭。由於遊戲中沒有空氣阻力,並且光之箭沒有箭身,箭的軌跡會是一條標準的拋物線,被軌跡穿過的所有靶子都認為被沫沫射中了,包括那些 只有端點被射中的靶子。這個遊戲有多種模式,其中沫沫最喜歡的是闖關模式。在闖關模式中,第一關只有乙個靶 子,射中這個靶子即可進入第二關,這時在第一關的基礎上會出現另外乙個靶子,若能夠一箭 雙雕射中這兩個靶子便可進入第三關,這時會出現第三個靶子。依此類推,每過一關都會新出 現乙個靶子,在第 k 關必須一箭射中前 k 關出現的所有 k 個靶子才能進入第 k+1 關,否則遊戲 結束。沫沫花了很多時間在這個遊戲上,卻最多只能玩到第七關「七星連珠」,這讓她非常困惑。 於是她設法獲得了每一關出現的靶子的位置,想讓你告訴她,最多能通過多少關

input

輸入檔案第一行是乙個正整數n,表示一共有n關。接下來有n行,第i+1行是用空格隔開的三個正整數xi,yi1,yi2(yi1output

僅包含乙個整數,表示最多的通關數。

sample input

52 8 12

5 4 5

3 8 10

6 2 3

1 3 7

sample output

3題解:對於該二次函式我們可以設為y=

ax²+b

x , 所以有 y

1<=ax

²1+b

x1<=y²

化簡可得 b

>=y1

/x1−

ax1

同理另半邊相同。這樣就形成了乙個以a,b為未知量的二元一次方程。而題目也就變成了半平面交問題。 通過二分答案, 複雜度就是nlogn的了。

#include#include#include#include#include#include#include#include#include#includeusing namespace std;

#define for(i,n) for(int i=1;i<=n;i++)

#define rep(i,n) for(int i=0;i=0;i--)

#define mem(a) memset(a,0,sizeof(a))

#define memi(a) memset(a,127,sizeof(a))

#define memi(a) memset(a,128,sizeof(a))

#define inf (2139062143)

#define phif (1000000006)

#define maxn (1000000+10)

#define dou long double

typedef long long ll;

const dou inf=1e15;

int tot,n;

struct point

point(dou x0,dou y0):x(x0),y(y0){}

};struct line

line(point s0,point e0):s(s0),e(e0){}

}l[200005],c[200005],l[200005];

dou operator *(point p1,point p2)

point operator -(point p1,point p2)

bool cmp(line p1,line p2)

bool check(int mid)

int cnt(1);

fork (i,2,tot)

if (l[i].k!=l[i-1].k) l[++cnt]=l[i];

int ll=1,rr=2;

c[1]=l[1];c[2]=l[2];

for (int i=3;i<=tot;i++)else righ=mid-1;

}printf("%d",ans);

}

BZOJ 2732 射箭(半平面交)

題意 給出n條第一象限內的豎直線段。求乙個最大的k,使得某條經過原點的拋物線穿過前k條線段。思路 設線段為 x,y1,y2 設拋物線為y ax 2 b x,那麼有 y1 ax 2 bx y2。據此可得到穿過該線段的拋物線引數a和b的兩個方程,這兩個方程是線性的。因此,可以半平面交,直到半平面內的點構...

半平面交模板

妹的,一直沒有想清楚無解的情況到底是如何判斷的。偷來乙個模板。半平面交的結果 1.凸多邊形 後面會講解到 2.無界,因為有可能若干半平面沒有形成封閉3.直線,線段,點,空 屬於特殊情況吧 演算法 1 根據上圖可以知道,運用給出的多邊形每相鄰兩點形成一條直線來切割原有多邊形,如果多邊形上的點i在有向直...

模板 半平面交

考慮用射線 乙個點和乙個向量 表示它左側的半平面 那麼我們可以先按與x軸正半軸夾角 可用atan2 y,x 實現 排序,然後再用雙端佇列維護當前在交中的射線即可 之所以要用雙端佇列,是因為新插入乙個半平面時隊首和隊尾都有可能被彈出,而且要注意的是,要先彈隊尾再彈隊首 在最後,還要再用隊首的彈一些隊尾...