計蒜客 商湯科技的行人檢測(困難) 概率 幾何

2021-08-01 19:47:04 字數 3919 閱讀 7720

分類:mathprobability

[計蒜客 商湯科技的行人檢測(困難)]

在這道題中,我們將行人的移動過程抽象為 旋轉、伸縮、平移,有 4 個 移動引數:θ,

scal

e,dx

,dy

​​ 。每次行人的移動過程會將行人對應的 nn 個點全部依次應用旋轉、伸縮、平移,對於平移前的點 (x, y)(x,y),進行每種操作後的座標如下:

旋轉後的座標為:(x

cosθ−y

sinθ,x

sinθ+y

cosθ

) ;

伸縮後的座標為:(x

×sca

le,y

×sca

le) ;

平移後的座標為:(x

+dx,

y+dy

) 。

由於行人移動的特殊性,我們可以確保

0ale≤

10 。和簡單版本不同的是,這道題處理的座標為浮點數而非整數。

很顯然,通過變換前後的正確座標,很容易算出行人的移動引數,但問題沒有這麼簡單。由於行人實際的移動並不會完全按照我們預想的方式進行,因此,會有一部分變換後的座標結果不正確,但可以確保 結果不正確的座標數量嚴格不超過一半。

你現在作為商湯科技的實習生,接手了這個有趣的挑戰:算出行人的移動引數。如果不存在一組合法的移動引數,則隨意輸出一組引數;如果有多種合法的移動引數,輸出其中任意一組合法的即可。

輸入格式

第一行輸入乙個整數

n ,表示行人抽象出的點數。

接下來

n行,每行

4 個 浮點數。前兩個數表示平移前的座標,後兩個數表示平移後的座標。

座標範圍在 −10

9 ​​ 到 109

​ 之間,輸入的座標都保留到

6 位小數。

對於中等版本,1≤

n≤500 ;

對於困難版本,1≤

n≤105

輸出格式

第一行輸出乙個浮點數

θ ,第二行輸出乙個浮點數 sc

ale ,第三行輸出兩個浮點數 dx

,dy 。

建議輸出保留到

10 位小數或以上。我們會按照 10−

3 ​的精度判斷是否有超過一半的點變換後的座標重合。

中等版本

在中等版本中,除了平移之外,還加入了旋轉和拉伸。可以發現只需要列舉哪兩對點是正確變換的,就可以計算出對應的拉伸、旋轉、平移的量,從而驗證是否有嚴格超過一半的點對滿足這組變換。時間複雜度o(

n3) 。注意特判只有乙個點對的情況。

困難版本

在困難版本中,點對數

n 從

100公升級到了

100000

。其演算法本質並沒有發生改變,依然是列舉兩對點,然後驗證。但是其列舉順序,必須從按順序列舉,改為隨機列舉,以避免最壞複雜度。注意到錯誤的點對數嚴格不超過一半,因此我們有超過 1/

4 的概率,列舉到的兩對點就是正確的。對應的,列舉一次失敗的概率就不足 3/

4 。這意味著:隨機列舉

10 次,失敗的概率不足

5.6%

;隨機列舉

20 次,失敗的概率不足

0.3%

;隨機列舉

50 次,失敗的概率不足

0.00005

% 。所以,只需要常數次列舉,基本可以保證找到答案。時間複雜度o(

n)。注意:

這題精度問題比較嚴重,盡量不要用at

an來求

θ ,精度誤差會比較大。

#include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

typedef

long

long ll;

typedef

long

double lb;

typedef

unsigned

long

long ull;

typedef pair pii;

typedef pairpll;

typedef pairplb;

typedef

vector

vi;

const

int inf = 0x3f3f3f3f;

const ll infl = 0x3f3f3f3f3f3f3f3fll;

const

long

double pi = acos(-1.0);

const

long

double eps = 1e-4;

void debug()

template

void debug (t f, r ...r)

template

inline

void umax(t &a, t b)

template

inline

void umin(t &a, t b)

template

inline

bool scan_d (t &ret)

template

void print(t x)

template

void println(t x)

const

int maxn = 1e5 + 5;

int n;

struct qnode

} cmd[maxn];

int sgn(const lb& a, const lb& b)

plb f(qnode qd, lb sita, lb scale, lb dx, lb dy)

int calc(lb sita, lb scale, lb dx, lb dy)

return cnt;

}inline lb dis(lb ax, lb ay, lb bx = 0.0, lb by = 0.0)

int main()

lb sita, scale, dx, dy, delta_x[2], delta_y[2], up, dw;

lb ans[4];

if(n == 1)

int cnt = 0;

for(int _ = 100; _--; )

cout

<< fixed << setprecision(11) << ans[0] << endl;

cout

<< fixed << setprecision(11) << ans[1] << endl;

cout

<< fixed << setprecision(11) << ans[2] << " "

<< ans[3] << endl;

}#ifdef ___local_wonzy___

cout

<< "time elapsed: "

<< 1.0 * clock() / clocks_per_sec * 1000

<< " ms."

<< endl;

#endif // ___local_wonzy___

return

0;}

計蒜客 商湯科技的行人檢測(隨機化 計算幾何)

題目鏈結 簡單中等 困難簡單版本 直接統計答案,數目到達一半即可。include using namespace std define rep i,a,b for int i a i b i define dec i,a,b for int i a i b i int n int a,b,c,d p...

計蒜客 商業資訊共享

有 n個公司,從每個公司都能單向地向另外乙個公司分享最新商業資訊,因為他們之間有著某種合作,你需要解決兩個問題 現在有乙個最新的商業資訊,至少需要告訴多少個公司,使得所有的公司最終都能得到該資訊。在原有基礎上,至少需要再讓多少對公司建立這種合作,使任意乙個公司獲得某個最新商業資訊後,經過若干次分享,...

2017計蒜之道初賽第四場 商湯科技的安全令牌

商湯科技致力於引領人工智慧核心 深度學習 技術突破,構建人工智慧 大資料分析行業解決方案。作為一家人工智慧公司,用機器自動地解決各類實際問題自然不在話下。近日,商湯科技推出了一套安全令牌,令牌如下圖所示 安全令牌上的小孔有 nn 行 mm 列,不過有些行和有些列已經用導線整體焊接了,共有 kk 根導...