トピック
http://poj.org/problem?id=1696
おそらく、質問の意味は、(最初の象限にある)一連のポイントを与えることであり、左端のポイントから最小のy値から始めて、左端まで行くことができます。何点。(以下は一例です)
分析
- いくつかの例を挙げると、すべてのポイントを確実に歩けるようです。
- 次に、開始点から開始し、反時計回りの極角が最小となる残りの点のいずれかを毎回次の点として選択します。
- | AB×AC | <0の場合に限り、ACはABの時計回り方向にあります。
プログラム
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int ans[20000],f[20000],n,T;
struct node{
int id,x,y;} a[20000];
bool cmp(node A,node B){
return A.y<B.y||A.y==B.y&&A.x<B.x;}
int cheng(node v1,node v2){
return v1.x*v2.y-v2.x*v1.y;}
int Dis(node A,node B){
return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);}
node Vct(node U,node V){
return (node){
0,V.x-U.x,V.y-U.y};}
void dfs(node A,int cnt){
if (cnt>n) return;
node ret;
ans[cnt]=f[A.id]=A.id;
for (int i=1; i<=n; i++) if (!f[a[i].id]) {ret=a[i]; break;}
for (int i=1; i<=n; i++)
if(!f[a[i].id] && (cheng(Vct(A,ret),Vct(A,a[i]))<0 || (cheng(Vct(A,ret),Vct(A,a[i]))==0 && Dis(A,a[i])<Dis(A,ret))))
ret=a[i];
dfs(ret,cnt+1);
}
int main(){
for(scanf("%d",&T); T--;){
memset(f,0,sizeof(f));
scanf("%d",&n);
for (int i=1; i<=n; i++) scanf("%d%d%d",&a[i].id,&a[i].x,&a[i].y);
sort(a+1,a+n+1,cmp);
dfs(a[1],1);
printf("%d ",n);
for (int i=1; i<=n; i++) printf("%d%c",ans[i],i==n?'\n':' ');
}
}
促す
- 同一線上の状況があり(外積は0)、現在のポイントに最も近いポイントを取得する必要があることに注意してください。