當前位置:首頁 » 操作系統 » 凸包硬幣演算法

凸包硬幣演算法

發布時間: 2022-12-31 18:42:02

Ⅰ 請問凸包演算法的時間復雜度的測試代碼怎麼寫

代碼一
(在編輯器中將"_ "(下劃線+空格)替換成兩個空格即可編譯; 注意要去掉開通的雙位元組中文空格,蛋疼的網路。)
#include <iostream>
#include <algorithm>
using namespace std;
struct point
{
_ _ int x;
_ _ int y;
} p[30005],res[30005];//p標記圖中所有的點,res標記凸包上的點
int cmp(point p1,point p2)
{
_ _ return p1.y < p2.y || (p1.y == p2.y && p1.x < p2.x);
}
bool ral(point p1,point p2,point p3) //用叉乘判斷點的位置
{
_ _ return (p2.x - p1.x)*(p3.y - p1.y) > (p3.x - p1.x)*(p2.y - p1.y);
}
int main()
{
_ _ int n,i;
_ _ while(scanf("%d",&n) != EOF) //一共有n個點
_ _ {
_ _ _ _ for(i = 0; i < n; i++)
_ _ _ _ _ _ scanf("%d%d",&p[i].x,&p[i].y);
__ _ _ if(n == 1)
_ _ _ _ {
_ _ _ _ _ _ printf("%d %d\n",p[0].x,p[0].y);
_ _ _ _ _ _ continue;
_ _ _ _ }
_ _ _ _ if(n == 2)
_ _ _ _ {
_ _ _ _ _ _ printf("%d %d\n",p[0].x,p[0].y);
_ _ _ _ _ _ printf("%d %d\n",p[1].x,p[1].y);
_ _ _ _ _ _ continue;
_ _ _ _ }
_ _ _ _ sort(p,p + n,cmp);
_ _ _ _ res[0] = p[0];
_ _ _ _ res[1] = p[1];
_ _ _ _ int top = 1;
_ _ _ _ for(i = 2; i < n; i++)
_ _ _ _ {
_ _ _ _ _ _ while(top && !ral(res[top],res[top - 1],p[i]))
_ _ _ _ _ _ top--;
_ _ _ _ _ _ res[++top] = p[i];
_ _ _ _ }
_ _ _ _ int len = top;
_ _ _ _ res[++top] = p[n - 2];
_ _ _ _ for(i = n - 3; i >= 0; i--)
_ _ _ _ {
_ _ _ _ _ _ while(top != len && !ral(res[top],res[top - 1],p[i]))
_ _ _ _ _ _ top--;
_ _ _ _ _ _ res[++top] = p[i];
_ _ _ _ }
_ _ _ _ for(i = 0; i < top; i++)
_ _ _ _ _ _ printf("%d %d\n",res[i].x,res[i].y);//輸出凸包上的點
_ _ }
_ _ return 0;
}
代碼二
#include <iostream> // 求點集合的凸包的gram演算法。n是頂點個數,x,y是頂點
坐標。
#include <fstream> // order 是按照頂點和左下腳的角度的排序後數組。
#include <deque> // tu即是逆時針的凸包上的頂點。
#include <math.h> //
using namespace std; //使用條件:1。點可以任意給,可重復。
// 2。三個以及以上的點。
ifstream fin("input.txt"); // 3。已經考慮了邊上有點的情況。
#define NN 1000
#define pi 3.1415827
typedef struct Cseg{
double x,y,tg;
}Cseg;
int n;
double x[NN],y[NN];
deque <Cseg> order;
deque <int> tu;
Cseg seg1;
deque <Cseg> ::iterator p1;
deque <int> ::iterator p,q;
void in();
void gram();
void makeorder(int s);
double dist(double x1,double yy1,double x2,double yy2);
double cross(double x1,double yy1,double x2,double yy2);
void out();
int main()
{
in();
gram();
out();
return 0;
}
void out()
{
int i;
for (i=0;i<tu.size();i++){
cout<<order[tu].x<<" "<<order[tu].y<<endl;
}
cout<<tu.size()<<" Edges Polydgon"<<endl;
return;
}
void in()
{
int i;
fin>>n;
for (i=0;i<n;i++)
fin>>x>>y;
return;
}
void gram()
{
int i,mm;
mm=0;
for (i=1;i<n;i++)
if (y[mm]>y+1e-9) mm=i;
else if (fabs(y[mm]-y)<1e-9 && x[mm]>x+1e-9) mm=i;
makeorder(mm);
seg1.x=x[mm];
seg1.y=y[mm];
tu.clear();
tu.push_back(0);
tu.push_back⑴;
tu.push_back⑵;
for (i=3;i<order.size();i++){
p=tu.end();
seg1.x=order.x;
seg1.y=order.y;
p--;
q=p-1;
if
(cross(order[*p].x-order[*q].x,order[*p].y-order[*q].y,order.x-order[*
q].x,order.y-order[*q].y)>1e-9)
tu.push_back(i);
else{
tu.pop_back();
i--;
continue;
//tu.push_back(i);
}
}//for
return;
}
void makeorder(int s)
{
int i;
double tg;
order.clear();
for (i=0;i<n;i++){
if (i==s) continue;
tg=atan2(y-y[s],x-x[s]);
seg1.x=x;
seg1.y=y;
seg1.tg=tg;
p1=order.begin();
while (p1!=order.end()){
if (fabs(tg-p1->tg)<1e-9){
if
(dist(x[s],y[s],x,y)>dist(x[s],y[s],p1->x,p1->y)+1e-9) {
p1->x=x;
p1->y=y;
}
break;
}
else
if (tg<p1->tg){
order.insert(p1,seg1);
break;
}
p1++;
}//while
if (p1==order.end()) order.insert(p1,seg1);
}//for
seg1.x=x[s];seg1.y=y[s];
order.insert(order.begin(),seg1);
//for (i=0;i<order.size();i++)
// printf("i=%d %lf %lf
%lf\n",i,order.x,order.y,order.tg*180/pi);
return;
}
double cross(double x1,double yy1,double x2,double yy2)
{
return (x1*yy2-x2*yy1);
}
double dist(double x1,double yy1,double x2,double yy2)
{
return pow((x1-x2)*(x1-x2)+(yy1-yy2)*(yy1-yy2),0.5);
}
代碼三
P標程{pku 1113 }
{$Q-,S-,R-}
const
pi=3.1415926575;
zero=1e-6;
maxn=1000;
maxnum=100000000;
var
ans,temp :extended;
n,tot :longint;
x,y :array[0..maxn]of extended;
zz,num :array[0..maxn]of longint;
procere swap(var ii,jj:extended);
var
t :extended;
begin
t:=ii;ii:=jj;jj:=t;
end;
procere init;
var
i,j :longint;
begin
readln(n,temp);
for i:=1 to n do readln(x[i],y[i]);
end;
function ok(x,midx,y,midy:extended):longint;
begin
if abs(x-midx)<=zero then
begin
if abs(midy-y)<=zero then exit(0);
if midy>y then exit⑴
else exit⑵;
end
else
begin
if x<midx then exit⑴
else exit⑵;
end;
end;
procere qsort(head,tail:longint);
var
i,j :longint;
midx,midy :extended;
begin
i:=head;
j:=tail;
midx:=x[(head+tail) div 2];
midy:=y[(head+tail) div 2];
repeat
while ok(x[i],midx,y[i],midy)=1 do inc(i);
while ok(x[j],midx,y[j],midy)=2 do dec(j);
if i<=j then
begin
swap(x[i],x[j]);
swap(y[i],y[j]);
inc(i);
dec(j);
end;
until i>j;
if i<tail then qsort(i,tail);
if j>head then qsort(head,j);
end;
function Plot(x1,y1,x2,y2:extended):extended;
begin
Plot:=x1*y2-x2*y1;
end;
function check(first,last,new:longint):boolean;
var
ax,ay,bx,by :extended;
Pt :extended;
begin
ax:=x[last]-x[first];ay:=y[last]-y[first];
bx:=x[new]-x[first];by:=y[new]-y[first];
if Plot(ax,ay,bx,by)<-zero then exit(true)
else exit(false);
end;
procere Tbao;
var
i,j,tail :longint;
begin
tot:=0;
zz[1]:=1;tail:=1;
for i:=2 to n do
begin
while (zz[tail]<>1)and check(zz[tail-1],zz[tail],i) do dec(tail);
inc(tail);
zz[tail]:=i;
end;
inc(tot,tail-1);
for i:=1 to tail-1 do
num[i]:=zz[i];
zz[1]:=n;tail:=1;
for i:=n-1 downto 1 do
begin
while (zz[tail]<>n)and check(zz[tail-1],zz[tail],i) do dec(tail);
inc(tail);
zz[tail]:=i;
end;
for i:=1 to tail-1 do
num[tot+i]:=zz[i];
inc(tot,tail-1);
end;
function dist(a,b:longint):extended;
begin
dist:=sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));
end;
procere main;
var
i,j :longint;
begin
qsort(1,n);
Tbao;
ans:=0;
for i:=1 to tot-1 do
ans:=ans+dist(num[i],num[i+1]);
ans:=ans+dist(num[tot],num[1]);
ans:=ans+temp*pi*2;
writeln(ans:0:0);
end;
begin
init;
main;
end.

Ⅱ 求二維凸包的增量演算法,最好能詳細解釋一下

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef double Type; // 注意下面的fabs().
const int maxn = 1005;
const double EPS = 1e-8;
const double Pi = acos(-1.0);
struct Point
{
Type x, y;
Point () {}
Point (Type & xx, Type & yy) : x(xx), y(yy) {}
};
// 判斷正負.
int dblcmp(Type d)
{
if (fabs(d) < EPS) return 0; // 注意數據類型不同,abs()也不同.
return d > 0 ? 1 : -1;
}
// 叉乘.
// cross proct of (c->a) and (c->b).
Type Cross(Point & c, Point a, Point b)
{
return (a.x - c.x) * (b.y - c.y) - (b.x - c.x) * (a.y - c.y);
}
Type Distance(Point & u, Point & v)
{
return sqrt( 0.0 + (u.x - v.x) * (u.x - v.x) + (u.y - v.y) * (u.y - v.y) );
}
int n;
Point point[maxn];
int Stack[maxn];
int top;
double ans;
bool cmp(const Point & a, const Point & b)
{
if (a.y == b.y) return a.x < b.x;
return a.y < b.y;
}
void graham_scan(void)
{
int i;
int temp_top;
if (n <= 1)
{
top = 0;
return ;
}
sort(point, point + n, cmp); // point[0]即為起點.
// 做右鏈.
top = -1;
Stack[++top] = 0; Stack[++top] = 1;
for (i = 2; i < n; i++)
{
while (top >= 1 && dblcmp(Cross(point[Stack[top - 1]], point[i], point[Stack[top]])) >= 0) top--; // 如果不能左轉,則退棧. 如果只要求極點,則共線的點也是不要的(即要加等於).
Stack[++top] = i;
}
temp_top = top; // 此時的棧頂元素一定是第n個點.
// 做左鏈.
Stack[++top] = n - 2;
for (i = n - 3; i >= 0; i--)
{
while (top >= temp_top + 1 && dblcmp(Cross(point[Stack[top - 1]], point[i], point[Stack[top]])) >= 0) top--; // 如果不能左轉,則退棧. 如果只要求極點,則共線的點也是不要的(即要加等於).
Stack[++top] = i;
}
// 此時的棧頂元素是第1個點.(如果凸包是一條直線,則左右鏈倒置相同.)
// 凸包的頂點為point[Stack[0]] 到 point[Stack[top - 1]].
}
int main(void)
{
int i;
scanf("%d", &n);
for (i = 0; i < n; i++)
{
scanf("%lf %lf", &point[i].x, &point[i].y);
}
graham_scan();
ans = 0;
for (i = 0; i < top; i++)
{
printf("%lf %lf\n", point[Stack[i]].x, point[Stack[i]].y);
ans += Distance(point[Stack[i]], point[Stack[i + 1]]); // point[Stack[top]] = point[Stack[0]].
}
printf("%lf\n", ans);
return 0;
}
/******************************************************************************************************************************************************/
/******************************************************************************************************************************************************/
/******************************************************************************************************************************************************/
/******************************************************************************************************************************************************/
/******************************************************************************************************************************************************/
/******************************************************************************************************************************************************/
/******************************************************************************************************************************************************/
/******************************************************************************************************************************************************/
/* 按照lrj的黑書來寫的.
適用條件:簡單多邊形(點按順時針或逆時針給出).
復雜度:O(n).
*/
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef double Type; // 注意下面的fabs().
const int maxn = 1005;
const double EPS = 1e-8;
const double Pi = acos(-1.0);
struct Point
{
Type x, y;
Point () {}
Point (Type & xx, Type & yy) : x(xx), y(yy) {}
};
// 判斷正負.
int dblcmp(Type d)
{
if (fabs(d) < EPS) return 0; // 注意數據類型不同,abs()也不同.
return d > 0 ? 1 : -1;
}
// 叉乘.
// cross proct of (c->a) and (c->b).
Type Cross(Point & c, Point a, Point b)
{
return (a.x - c.x) * (b.y - c.y) - (b.x - c.x) * (a.y - c.y);
}
Type Distance(Point & u, Point & v)
{
return sqrt( 0.0 + (u.x - v.x) * (u.x - v.x) + (u.y - v.y) * (u.y - v.y) );
}
int n;
Point point[maxn];
int Stack[2 * maxn]; // 兩頭棧.
int bot, top; // 棧底,棧頂.
double ans;
void Melkman(void)
{
int i;
int temp;
Stack[n] = 0;
// 注意:前三個點不能是共線的.
for (i = 1; i < n; i++)
{
Stack[n + 1] = i; // 當三點平行時要的是後一個點.
if (dblcmp(Cross(point[Stack[n]], point[Stack[n + 1]], point[i + 1]))) break; // 前三個點不共線.
}
bot = n, top = n + 1;
Stack[++top] = Stack[--bot] = i + 1;
// 保證開始的三個點成右手系,否則交換Stack[n]和Stack[n + 1] .
if (dblcmp(Cross(point[Stack[n]], point[Stack[n + 1]], point[Stack[n + 2]])) < 0)
{
temp = Stack[n]; Stack[n] = Stack[n + 1]; Stack[n + 1] = temp;
}
// 維護棧里的點為右手系(即棧中任意連續三點組成的路徑是左旋的,或成直線).
for (i = i + 2; i < n; i++)
{
if (dblcmp(Cross(point[Stack[top - 1]], point[Stack[top]], point[i])) > 0 &&
dblcmp(Cross(point[Stack[bot]], point[Stack[bot + 1]], point[i])) > 0)
{ // 如果該點對於棧頂左旋且對於棧底右旋,則說明該點在凸包內.
continue;
}
while (dblcmp(Cross(point[Stack[top - 1]], point[Stack[top]], point[i])) <= 0) top--;
Stack[++top] = i;
while (dblcmp(Cross(point[Stack[bot]], point[Stack[bot + 1]], point[i])) <= 0) bot++;
Stack[--bot] = i;
}
}
int main(void)
{
int i;
scanf("%d", &n);
for (i = 0; i < n; i++)
{
scanf("%lf %lf", &point[i].x, &point[i].y);
}
Melkman(); // 得到的凸包點序列也是按極角序的.
cout << top - bot << endl;
for (i = bot; i < top; i++)
{
printf("%lf %lf\n", point[Stack[i]].x, point[Stack[i]].y);
ans += Distance(point[Stack[i]], point[Stack[i + 1]]); // Stack[top]為第1個點.
}
printf("%lf\n", ans);
return 0;
}

Ⅲ 空間點集的帶權Delaunay三角化演算法

構造點集的Delaunay三角化的著名增量演算法有兩種:一種稱為局部變換法(也稱為Flip-ping演算法),另外一種稱為Bowyer/Watson演算法。構造空間點集的帶權Delaunay三角化演算法也主要有兩種,分別是以上兩種演算法的推廣。我們只介紹推廣後的Bowyer/Watson演算法,稱之為「帶權Delaunay空洞演算法構造點集的帶權Delaunay三角化」演算法。

1.帶權Delaunay空洞定義

給定Ed空間的點集S,設有一點p∉S位於點集S的凸包中。Δ=ΔT是點集S的帶權Delaunay三角化中的任意一個單純形,z=z(Δ)為Δ的正交中心。如果滿足wp>πz(p),則稱為Δ和p點沖突(也可以將單純形的正交中心理解為權為正交球半徑平方的帶權點,當該點與p點干涉時,單純形和p點沖突)。在帶權Delaunay三角化的結果中,將所有與p點沖突的單純形從帶權Delaunay三角化中刪除,將形成一個空洞,稱為帶權Delaunay空洞,又稱為Regular空洞(Regular Cavity)。

根據d維空間的帶權Delaunay三角化與d+1維空間的凸包之間的關系,可以在d+1維空間的凸包CH(S+)上考察將p點加入帶權Delaunay三角化中帶權Delaunay空洞的形成過程:如果Δ=ΔT和p點沖突,意味著p+點在過ΔT+=CH(T+)的超平面的下方。在帶權Delaunay三角化中,刪除CH(S+)的所有p+在其下方的下部小面對應的單純形,形成帶權Delaunay空洞。

2.帶權Delaunay空洞構造演算法

帶權Delaunay空洞構造演算法的思路如下:帶權Delaunay空洞構造演算法是一種增量演算法,S中的點是逐點加入、逐點處理的。與局部變換演算法一樣,需要選擇一個初始的足夠大的d-單純形。設點集S={p1,p2,…,pn},選擇d+1的權為0的點構成點集S0={p-d,p-d+l,…,p0},構造一個d-單純形ΔS0=CH(S0)。選擇的S0要保證ΔS0包含S中所有的點,並且保證WD(S)的每個d-單純形是WD(S ∪ S0)的d-單純形。

定義Si={p-d,p-d+1,…,pi}。給定R(Si-1),設Δ=ΔT是WD(Si-1)中包含pi點的d-單純形。如果加入pi後,Δ仍然是正則的,則WD(Si)=WD(Si-1)。否則,刪除Δ,並且根據鄰接關系,刪除Δ周圍所有與pi沖突的d-單純形,得到pi點的帶權Delaunay空洞,並且將空洞多面體的每個小面的頂點和pi相連形成新的d-單純形,從而得到WD(Si)。當點集S中所有的點處理完成後,將得到WD(S)。

演算法:帶權Delaunay空洞構造演算法

{

1 構造WD(S0)=ΔS0

2 for i:=1 to n do

3 在WD(Si-1)中找到包含pi點的d-單純形Δ

4 if WD(T ∪{pi})≠ΔT then

刪除Δ,並且根據鄰接關系,刪除Δ周圍所有與pi沖突的d-單純形,得到pi點的帶權D elaunay空洞

6 while pi點的帶權Delaunay空洞中存在未處理的小面do

7 得到一個未處理的小面,設其所有頂點組成的集合為U,生成新的d-單純形ΔU ∪{pi},在點集Si中是正則的,也就是說Δ屬於W D(Si)設置新生成的d-單純形之間的鄰接關系,以及新的

地下水三維可視化系統開發與應用

Ⅳ 凸包的平面求法

這個演算法是由數學大師葛立恆(Graham)發明的,他曾經是美國數學學會(AMS)主席、AT&T首席科學家以及國際雜技師協會(IJA)主席。
問題
給定平面上的二維點集,求解其凸包。
過程
⒈ 在所有點中選取y坐標最小的一點H,當作基點。如果存在多個點的y坐標都為最小值,則選取x坐標最小的一點。坐標相同的點應排除。然後按照其它各點p和基點構成的向量<H,p>;與x軸的夾角進行排序,夾角由大至小進行順時針掃描,反之則進行逆時針掃描。實現中無需求得夾角,只需根據餘弦定理求出向量夾角的餘弦值即可。以下圖為例,基點為H,根據夾角由小至大排序後依次為H,K,C,D,L,F,G,E,I,B,A,J。下面進行逆時針掃描。

⒉ 線段<H,K>;一定在凸包上,接著加入C。假設線段<K,C>;也在凸包上,因為就H,K,C三點而言,它們的凸包就是由此三點所組成。但是接下來加入D時會發現,線段<K,D>;才會在凸包上,所以將線段<K,C>;排除,C點不可能是凸包。
⒊ 即當加入一點時,必須考慮到前面的線段是否會出現在凸包上。從基點開始,凸包上每條相臨的線段的旋轉方向應該一致,並與掃描的方向相反。如果發現新加的點使得新線段與上線段的旋轉方向發生變化,則可判定上一點必然不在凸包上。實現時可用向量叉積進行判斷,設新加入的點為pn + 1,上一點為pn,再上一點為pn - 1。順時針掃描時,如果向量<pn - 1,pn>;與<pn,pn + 1>;的叉積為正(逆時針掃描判斷是否為負),則將上一點刪除。刪除過程需要回溯,將之前所有叉積符號相反的點都刪除,然後將新點加入凸包。
在上圖中,加入K點時,由於線段<H,C>要旋轉到<H,K>的角度,為順時針旋轉,所以C點不在凸包上,應該刪除,保留K點。接著加入D點,由於線段<K,D>要旋轉到<H,K>的角度,為逆時針旋轉,故D點保留。按照上述步驟進行掃描,直到點集中所有的點都遍歷完成,即得到凸包。
復雜度
這個演算法可以直接在原數據上進行運算,因此空間復雜度為O⑴。但如果將凸包的結果存儲到另一數組中,則可能在代碼級別進行優化。由於在掃描凸包前要進行排序,因此時間復雜度至少為快速排序的O(nlgn)。後面的掃描過程復雜度為O(n),因此整個演算法的復雜度為O(nlgn)。 對於一個有三個或以上點的點集Q,過程如下:
計算點集最右邊的點為凸包的頂點的起點,如上圖的P3點。
Do
For i = 0 To 總頂點數
計算有向向量P3->Pi
If 其餘頂點全部在有向向量P3->Pi的左側或右側,則Pi點為凸包的下一頂點
Pi點加入凸包列表
GoTo 1
End If
Next
Exit Do
1:
Loop
此過程執行後,點按極角自動順時針或逆時針排序,只需要按任意兩點的次序就可以了。而左側或右側的判斷可以用前述的矢量點積性質實現。 constpi=3.1415926575;zero=1e-6;maxn=1000;maxnum=100000000;varans,temp:extended;n,tot:longint;x,y:array[0..maxn]ofextended;zz,num:array[0..maxn]oflongint;procereswap(varii,jj:extended);vart:extended;begint:=ii;ii:=jj;jj:=t;end;procereinit;vari,j:longint;beginreadln(n);fori:=1tondoreadln(x[i],y[i]);end;functionok(x,midx,y,midy:extended):longint;beginifabs(x-midx)<=zerothenbeginifabs(midy-y)<=zerothenexit(0);ifmidy>ythenexit(1)elseexit(2);endelsebeginifx<midxthenexit(1)elseexit(2);end;end;procereqsort(head,tail:longint);vari,j:longint;midx,midy:extended;begini:=head;j:=tail;midx:=x[(head+tail)div2];midy:=y[(head+tail)div2];repeatwhileok(x[i],midx,y[i],midy)=1doinc(i);whileok(x[j],midx,y[j],midy)=2dodec(j);ifi<=jthenbeginswap(x[i],x[j]);swap(y[i],y[j]);inc(i);dec(j);end;untili>j;ifi<tailthenqsort(i,tail);ifj>headthenqsort(head,j);end;functionPlot(x1,y1,x2,y2:extended):extended;beginPlot:=x1*y2-x2*y1;end;functioncheck(first,last,new:longint):boolean;varax,ay,bx,by:extended;Pt:extended;beginax:=x[last]-x[first];ay:=y[last]-y[first];bx:=x[new]-x[first];by:=y[new]-y[first];ifPlot(ax,ay,bx,by)<=0thenexit(true)elseexit(false);end;procereTbao;vari,j,tail:longint;begintot:=0;zz[1]:=1;tail:=1;fori:=2tondobeginwhile(zz[tail]<>1)andcheck(zz[tail-1],zz[tail],i)dodec(tail);inc(tail);zz[tail]:=i;end;inc(tot,tail-1);fori:=1totail-1donum[i]:=zz[i];zz[1]:=n;tail:=1;fori:=n-1downto1dobeginwhile(zz[tail]<>n)andcheck(zz[tail-1],zz[tail],i)dodec(tail);inc(tail);zz[tail]:=i;end;fori:=1totail-1donum[tot+i]:=zz[i];inc(tot,tail-1);end;functiondist(a,b:longint):extended;begindist:=sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));end;proceremain;vari,j:longint;beginqsort(1,n);Tbao;ans:=0;fori:=1totot-1doans:=ans+dist(num[i],num[i+1]);ans:=ans+dist(num[tot],num[1]);ans:=ans+temp*pi*2;writeln(ans:0:1);end;begininit;main;end.

Ⅳ 程序員必須掌握哪些演算法

一.基本演算法:

枚舉. (poj1753,poj2965)

貪心(poj1328,poj2109,poj2586)

遞歸和分治法.

遞推.

構造法.(poj3295)

模擬法.(poj1068,poj2632,poj1573,poj2993,poj2996)

二.圖演算法:

圖的深度優先遍歷和廣度優先遍歷.

最短路徑演算法(dijkstra,bellman-ford,floyd,heap+dijkstra)
(poj1860,poj3259,poj1062,poj2253,poj1125,poj2240)
最小生成樹演算法(prim,kruskal)
(poj1789,poj2485,poj1258,poj3026)
拓撲排序 (poj1094)

二分圖的最大匹配 (匈牙利演算法) (poj3041,poj3020)

最大流的增廣路演算法(KM演算法). (poj1459,poj3436)

三.數據結構.

串 (poj1035,poj3080,poj1936)

排序(快排、歸並排(與逆序數有關)、堆排) (poj2388,poj2299)

簡單並查集的應用.

哈希表和二分查找等高效查找法(數的Hash,串的Hash)
(poj3349,poj3274,POJ2151,poj1840,poj2002,poj2503)
哈夫曼樹(poj3253)



trie樹(靜態建樹、動態建樹) (poj2513)

四.簡單搜索

深度優先搜索 (poj2488,poj3083,poj3009,poj1321,poj2251)

廣度優先搜索(poj3278,poj1426,poj3126,poj3087.poj3414)

簡單搜索技巧和剪枝(poj2531,poj1416,poj2676,1129)

五.動態規劃

背包問題. (poj1837,poj1276)

型如下表的簡單DP(可參考lrj的書 page149):
E[j]=opt{D+w(i,j)} (poj3267,poj1836,poj1260,poj2533)
E[i,j]=opt{D[i-1,j]+xi,D[i,j-1]+yj,D[i-1][j-1]+zij} (最長公共子序列) (poj3176,poj1080,poj1159)
C[i,j]=w[i,j]+opt{C[i,k-1]+C[k,j]}.(最優二分檢索樹問題)
六.數學

組合數學:
1.加法原理和乘法原理.
2.排列組合.
3.遞推關系.
(POJ3252,poj1850,poj1019,poj1942)
數論.
1.素數與整除問題
2.進制位.
3.同餘模運算.
(poj2635, poj3292,poj1845,poj2115)
計算方法.
1.二分法求解單調函數相關知識.(poj3273,poj3258,poj1905,poj3122)
七.計算幾何學.

幾何公式.

叉積和點積的運用(如線段相交的判定,點到線段的距離等). (poj2031,poj1039)

多邊型的簡單演算法(求面積)和相關判定(點在多邊型內,多邊型是否相交)
(poj1408,poj1584)
凸包. (poj2187,poj1113)

中級(校賽壓軸及省賽中等難度):
一.基本演算法:

C++的標准模版庫的應用. (poj3096,poj3007)

較為復雜的模擬題的訓練(poj3393,poj1472,poj3371,poj1027,poj2706)

二.圖演算法:

差分約束系統的建立和求解. (poj1201,poj2983)

最小費用最大流(poj2516,poj2516,poj2195)

雙連通分量(poj2942)

強連通分支及其縮點.(poj2186)

圖的割邊和割點(poj3352)

最小割模型、網路流規約(poj3308)

三.數據結構.

線段樹. (poj2528,poj2828,poj2777,poj2886,poj2750)

靜態二叉檢索樹. (poj2482,poj2352)

樹狀樹組(poj1195,poj3321)

RMQ. (poj3264,poj3368)

並查集的高級應用. (poj1703,2492)

KMP演算法. (poj1961,poj2406)

四.搜索

最優化剪枝和可行性剪枝

搜索的技巧和優化 (poj3411,poj1724)

記憶化搜索(poj3373,poj1691)

五.動態規劃

較為復雜的動態規劃(如動態規劃解特別的旅行商TSP問題等)
(poj1191,poj1054,poj3280,poj2029,poj2948,poj1925,poj3034)
記錄狀態的動態規劃. (POJ3254,poj2411,poj1185)

樹型動態規劃(poj2057,poj1947,poj2486,poj3140)

六.數學

組合數學:
1.容斥原理.
2.抽屜原理.
3.置換群與Polya定理(poj1286,poj2409,poj3270,poj1026).
4.遞推關系和母函數.
數學.
1.高斯消元法(poj2947,poj1487, poj2065,poj1166,poj1222)
2.概率問題. (poj3071,poj3440)
3.GCD、擴展的歐幾里德(中國剩餘定理) (poj3101)
計算方法.
1.0/1分數規劃. (poj2976)
2.三分法求解單峰(單谷)的極值.
3.矩陣法(poj3150,poj3422,poj3070)
4.迭代逼近(poj3301)
隨機化演算法(poj3318,poj2454)
雜題(poj1870,poj3296,poj3286,poj1095)
七.計算幾何學.

坐標離散化.

掃描線演算法(例如求矩形的面積和周長並,常和線段樹或堆一起使用)
(poj1765,poj1177,poj1151,poj3277,poj2280,poj3004)
多邊形的內核(半平面交)(poj3130,poj3335)

幾何工具的綜合應用.(poj1819,poj1066,poj2043,poj3227,poj2165,poj3429)

高級(regional中等難度):
一.基本演算法要求:

代碼快速寫成,精簡但不失風格

(poj2525,poj1684,poj1421,poj1048,poj2050,poj3306)

保證正確性和高效性. poj3434

二.圖演算法:

度限制最小生成樹和第K最短路. (poj1639)

最短路,最小生成樹,二分圖,最大流問題的相關理論(主要是模型建立和求解)
(poj3155, poj2112,poj1966,poj3281,poj1087,poj2289,poj3216,poj2446
最優比率生成樹. (poj2728)

最小樹形圖(poj3164)

次小生成樹.

無向圖、有向圖的最小環

三.數據結構.

trie圖的建立和應用. (poj2778)

LCA和RMQ問題(LCA(最近公共祖先問題) 有離線演算法(並查集+dfs) 和 在線演算法(RMQ+dfs)).(poj1330)
雙端隊列和它的應用(維護一個單調的隊列,常常在動態規劃中起到優化狀態轉移的目的). (poj2823)
左偏樹(可合並堆).

後綴樹(非常有用的數據結構,也是賽區考題的熱點).(poj3415,poj3294)
四.搜索

較麻煩的搜索題目訓練(poj1069,poj3322,poj1475,poj1924,poj2049,poj3426)

廣搜的狀態優化:利用M進制數存儲狀態、轉化為串用hash表判重、按位壓縮存儲狀態、雙向廣搜、A*演算法. (poj1768,poj1184,poj1872,poj1324,poj2046,poj1482)

深搜的優化:盡量用位運算、一定要加剪枝、函數參數盡可能少、層數不易過大、可以考慮雙向搜索或者是輪換搜索、IDA*演算法. (poj3131,poj2870,poj2286)

五.動態規劃

需要用數據結構優化的動態規劃.(poj2754,poj3378,poj3017)
四邊形不等式理論.

較難的狀態DP(poj3133)

六.數學

組合數學.
1.MoBius反演(poj2888,poj2154)
2.偏序關系理論.
博奕論.
1.極大極小過程(poj3317,poj1085)
2.Nim問題.
七.計算幾何學.

半平面求交(poj3384,poj2540)

可視圖的建立(poj2966)

點集最小圓覆蓋.

對踵點(poj2079)

Ⅵ 周培德演算法

平面點集三角剖分的周培德演算法是周培德於1996提出的(周培德,1996,2000),該演算法首先對點集逐層求凸包,如圖3.8(a)所示為需要剖分的點集,圖3.8(b)為對點集逐層求凸包,對點集逐層求凸包時可能存在1個或2個孤立點無法組成凸包,此時恰好沒有剩下孤立的點;然後將兩兩凸包之間的環狀區域分割成三角形,最後調整相鄰環域的三角剖分便能獲得最小權的三角剖分,如圖3.8(c)為從內到外將凸包之間的環狀區域分割成三角形,圖3.8(d)為點集的三角剖分結果。

第十三步:對以Cm中的邊(或已變動的邊)為共用邊的三角形對,採用第十二步的方法檢查是否需要改變原有的三角剖分。然後,沿Cm-1,…,C2的各條邊(或已變動的邊)尋找兩個有共用邊的三角形對,並用第十二步的方法檢查是否需要改變原來的三角剖分,直到所有凸殼的邊檢查完為止。

Ⅶ matlab如何求大量數據中分布最多的范圍及中心點。

樓主是不是想求出一個最小半徑的圓,圓內包含所有的點?這個問題很有趣。

尋找這個圓的時候注意一下幾點:
1.這個圓必然穿過圖中某些靠外圍的點,這樣才是最小半徑的圓。
2.幾何中我們知道,三個點可以確定一個圓, 我們就是需要找出這三個點來.

演算法如下:1.先求這些點對應的凸包,已經有現成的演算法。
2.生成凸包後,在看凸包上哪三點確定的圓可以包含凸包。

當然如果樓主討論的不是以上所述,而是模式分類的話,建議看看數據分類方法。可以搜索關鍵字:Gaussian mixtrual model, expectation-maximization algorithm 和 k-mean algorithm 學習下相關的知識。

Ⅷ 挑戰程序設計競賽(第2版)的目錄

《挑戰程序設計競賽(第2版)》
第1章蓄勢待發——准備篇1 1.1 何謂程序設計競賽2 1.2 最負盛名的程序設計競賽5 1.2.1 世界規模的大賽——google code jam(gcj)5 1.2.2 向高排名看齊!——topcoder5 1.2.3 歷史最悠久的競賽—— acm-icpc6 1.2.4 面向中學生的信息學奧林匹克競賽——joi-ioi6 1.2.5 通過網路自動評測——online judge(oj)6 1.3 本書的使用方法7 1.3.1 本書所涉及的內容7 1.3.2 所用的編程語言7 1.3.3 題目描述的處理7 1.3.4 程序結構7 1.3.5 練習題8 1.3.6 讀透本書後更上一層樓的練習方法8 1.4 如何提交解答9 1.4.1 poj的提交方法9 1.4.2 gcj的提交方法11 1.5 以高效的演算法為目標15
.1.5.1 什麼是復雜度15 1.5.2 關於運行時間15 1.6 輕松熱身16 1.6.1 先從簡單題開始16 1.6.2 poj的題目ants18 1.6.3 難度增加的抽簽問題20 第2章初出茅廬——初級篇25 2.1 最基礎的「窮竭搜索」26 2.1.1 遞歸函數26 2.1.2 棧27 2.1.3 隊列28 2.1.4 深度優先搜索29 2.1.5 寬度優先搜索33 2.1.6 特殊狀態的枚舉37 2.1.7 剪枝38 2.2 一往直前!貪心法39 2.2.1 硬幣問題39 2.2.2 區間問題40 2.2.3 字典序最小問題43 2.2.4 其他例題45 2.3 記錄結果再利用的「動態規劃」51 2.3.1 記憶化搜索與動態規劃51 2.3.2 進一步探討遞推關系57 2.3.3 有關計數問題的dp66 2.4 加工並存儲數據的數據結構70 2.4.1 樹和二叉樹70 2.4.2 優先隊列和堆71 2.4.3 二叉搜索樹77 2.4.4 並查集84 2.5 它們其實都是「圖」91 2.5.1 圖是什麼91 2.5.2 圖的表示94 2.5.3 圖的搜索97 2.5.4 最短路問題99 2.5.5 最小生成樹105 2.5.6 應用問題107 2.6 數學問題的解題竅門113 2.6.1 輾轉相除法113 2.6.2 有關素數的基礎演算法117 2.6.3 模運算121 2.6.4 快速冪運算122 2.7 一起來挑戰gcj的題目(1)125 2.7.1 minimum scalar proct125 2.7.2 crazy rows127 2.7.3 bribe the prisoners129 2.7.4 millionaire132 第3章出類拔萃——中級篇137 3.1 不光是查找值!「二分搜索」138 3.1.1 從有序數組中查找某個值138 3.1.2 假定一個解並判斷是否可行140 3.1.3 最大化最小值142 3.1.4 最大化平均值143 3.2 常用技巧精選(一)146 3.2.1 尺取法146 3.2.2 反轉(開關問題)150 3.2.3 彈性碰撞158 3.2.4 折半枚舉(雙向搜索)160 3.2.5 坐標離散化164 3.3 活用各種數據結構167 3.3.1 線段樹167 3.3.2 binary indexed tree174 3.3.3 分桶法和平方分割183 3.4 熟練掌握動態規劃191 3.4.1 狀態壓縮dp191 3.4.2 矩陣的冪199 3.4.3 利用數據結構高效求解206 3.5 藉助水流解決問題的網路流209 3.5.1 最大流209 3.5.2 最小割212 3.5.3 二分圖匹配217 3.5.4 一般圖匹配220 3.5.5 匹配、邊覆蓋、獨立集和頂點覆蓋221 3.5.6 最小費用流222 3.5.7 應用問題228 3.6 與平面和空間打交道的計算幾何250 3.6.1 計算幾何基礎250 3.6.2 極限情況255 3.6.3 平面掃描258 3.6.4 凸包260 3.6.5 數值積分263 3.7 一起來挑戰gcj的題目(2)267 3.7.1 numbers267 3.7.2 no cheating269 3.7.3 stock charts271 3.7.4 watering plants273 3.7.5 number sets278 3.7.6 wi-fi towers280 第4章登峰造極——高級篇285 4.1 更加復雜的數學問題286 4.1.1 矩陣286 4.1.2 模運算的世界291 4.1.3 計數295 4.1.4 具有對稱性的計數300 4.2 找出遊戲的必勝策略305 4.2.1 游戲與必勝策略305 4.2.2 nim311 4.2.3 grundy數315 4.3 成為圖論大師之路320 4.3.1 強連通分量分解320 4.3.2 2-sat324 4.3.3 lca328 4.4 常用技巧精選(二)335 4.4.1 棧的運用335 4.4.2 雙端隊列的運用337 4.4.3 倍增法345 4.5 開動腦筋智慧搜索350 4.5.1 剪枝350 4.5.2 a*與ida*356 4.6 劃分、解決、合並:分治法359 4.6.1 數列上的分治法359 4.6.2 樹上的分治法360 4.6.3 平面上的分治法364 4.7 華麗地處理字元串368 4.7.1 字元串上的動態規劃演算法368 4.7.2 字元串匹配373 4.7.3 後綴數組378 4.8 一起來挑戰gcj的題目(3)387 4.8.1 mine layer387 4.8.2 year of more code jam392 4.8.3 football team395 4.8.4 endless knight399 4.8.5 the year of code jam403 本書中未涉及的拓展主題408 書中例題列表411 參考文獻413

Ⅸ Bezier曲線定義與性質,分別給出演算法簡述。

一、Bezier曲線定義:
給定n+1個控制頂點Pi(i=0~n) ,則Bezier曲線定義為:
P(t)=∑Bi,n(t)Pi u∈[0,1]
其中:Bi,n(t)稱為基函數。
Bi,n(t)=Ci nti (1-t)n-i
Ci n=n!/(i!*(n-i)!)

二、Bezier曲線性質
1、端點性質:
a)P(0)=P0, P(1)=Pn, 即:曲線過二端點。
b)P』(0)=n(P1-P0), P』(1)=n(Pn-Pn-1)
即:在二端點與控制多邊形相切。
2、凸包性:Bezier曲線完成落在控制多邊形的凸包內。
3、對稱性:由Pi與Pn-i組成的曲線,位置一致,方向相反。
4、包絡性:Pn (t)=(1-t)Pn-1 (t)+tPn-1 (t)

熱點內容
比爾密碼價值多少人民幣 發布:2025-05-10 10:26:20 瀏覽:446
怎樣用電腦遠程連接撥號伺服器 發布:2025-05-10 10:17:44 瀏覽:466
伺服器需要什麼系統 發布:2025-05-10 10:17:38 瀏覽:195
中國電信拍攝腳本 發布:2025-05-10 10:17:00 瀏覽:457
43魔獸世界POR腳本 發布:2025-05-10 10:06:15 瀏覽:731
群輝外網訪問nas 發布:2025-05-10 10:05:35 瀏覽:472
ftp記錄傳輸文件 發布:2025-05-10 09:56:53 瀏覽:560
社保的查詢密碼是什麼 發布:2025-05-10 09:51:49 瀏覽:619
php獲取ip的函數 發布:2025-05-10 09:43:48 瀏覽:152
金立怎麼刷機解鎖密碼 發布:2025-05-10 09:43:45 瀏覽:761