水果忍者(找一條穿過所有線的線 思維)

2021-09-13 21:49:47 字數 1497 閱讀 8795

原題:

題意:

有n條豎線,給出位置和長度,你需要找出一條線,穿過所有的線(包括邊界點)。要求線的兩個頂點座標為整數。

方法一:

三分在-1e6上的可行區域,check函式為:從這個點投出光,穿過每條線段後可能會遮擋一部分,判斷是否有一絲光穿過所有線段。複雜度o(n

logn

)o(nlogn)

o(nlog

n)。但是找到這個區域後找兩個整數點就比較麻煩了。

方法二:

發現不管怎麼畫,都可以通過微調答案線使之穿過至少乙個上端點,乙個下端點。所以我列舉每個上端點作為答案端點。

顯然,對於引伸出的線,所有上端點都應該在其上方,所有下端點都在其下方。

為了使所有上端點在上面,對於左邊的上端點,左邊要往下壓(類似於蹺蹺板),那麼斜率越來越大;

對於右邊的上端點,右邊往下壓,斜率越來越小;此時判斷斜率是否小於左邊的最大斜率,如果是,則說明不存在經過當前點的線,使所有點在其上方。

下端點類似,只不過左邊往上斜率越來越小,右邊往上斜率越來越大。

結束之後有:

任意滿足比左上大,比右上小的斜率k,都可以使全部上端點處於上方;

比右下大,左下小的,所有下端點處於其下方;

此時若有乙個k同時滿足這兩個條件,就是答案。

複雜度o(n

2)

o(n^2)

o(n2)。

#include

using

namespace std;

const

int maxn=

1e4+4;

struct node

}e[maxn]

;int

main()

sort

(e+1

,e+1

+n);

for(

register

int i=

1;i<=n;i++

)for

(register

int j=i+

1;j<=n;j++)}

}if(!can)

continue

;for

(register

int j=

1;j)for

(register

int j=i+

1;j<=n;j++)}

}if(!can)

continue;if

(downl>=upr&&upr>=downr&&p2>0)

else

if(downl>=upl&&downl<=upr&&p3>0)

else

if(downr>=upl&&downr<=upr&&p4>0)

else

if(upl>=downr&&upl<=downl&&p1>0)

}}

簡單迷宮的實現 找一條通路

include include includeusing namespace std 求解路徑的基本思想 1.如果當前路徑能夠通過,將當前路經進行壓棧,為了回退 回溯法 並將走過的路標記成2 不能走1,0可以走 2.如果當前路徑上下左右都不能通過,則出棧 回溯 並且將當前路徑標為3 即將回溯路徑標記...

一條語句計算所有遞增序列的結果

1.遞增序列的概念 一串數的序列,相領兩個數之間的差值是固定的,則此數列遞增序列,如 1,2,3,4,5,6,7,8,9,10 差1 1,3,5,7,9,11 差2 大家一般都會了解,它的規律是第1個數與倒數第1個數的和,與第二個數與倒數第二個數的和是一樣的。這樣可以有這樣的計算方法 begin e...

Linux 一條命令殺死占用埠的所有程序

linux網路程式設計的實驗中遇到了開啟server後用ctrl c退出但是埠仍被server占用的情況,首先可以用lsof檢視占用埠的程序號 lsof i 埠號然後kill掉占用程序,就可以再次啟動server了 kill 9 程序號sudo kill 9 lsof i 埠號 t linux如何檢...