題意:有個東西,要喫地圖上的點,但是隻能直走或者向左拐,而且不能與之前的路線相交,問最多能喫多少
思路:向左拐的話開始以爲是叉乘,後來天真的亂寫錯了之後看題解,發現最多能喫多少完全是坑,因爲能全喫完= =,其實畫一畫完全能發現,就是從最下面的點開始,然後繞着圈喫嘛。。於是這道題也是這麼解的,先找到最下面的點,然後找到偏轉角度最小的點,就這樣走下去就可以。。三點共線的時候開始沒考慮也A了,後來想了想應該是取距離相對最小的那個點(然後就可以接着走向下一個點了)
代碼:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<queue>
#include<list>
using namespace std;
const double INF = 1e200;
const double EP = 1e-8;
const int maxn = 4000;
const double PI = acos(-1);
struct POINT{///點 定義
double x;
double y;
int id;
POINT(double a = 0,double b = 0){x = a;y = b;}
};
struct SEGMENT{///line segment///線段 定義
POINT s;
POINT e;
SEGMENT(POINT a,POINT b){s = a;e = b;}
SEGMENT(){}
};
struct LINE{///ax + by + c = 0&&a >= 0///一般式
double a;
double b;
double c;
LINE(double da,double db,double dc){a = da;b = db;c = dc;}
LINE(double x1,double y1,double x2,double y2){///根據兩個點求出一般式
a = y1 - y2;b = x2 - x1;c = x1*y2 - x2*y1;
if(a < 0){a*=-1;b*=-1;c*=-1;}
}
};
double multiply(POINT sp,POINT ep,POINT op){///向量op->sp X op->ep的叉乘,小於0:ep在op->sp順時針方向//大於0:0:ep在op->sp逆時針方向//等於0:三點共線
return ((sp.x - op.x)*(ep.y - op.y) - (ep.x - op.x)*(sp.y - op.y));
}
double dotmultiply(POINT p1,POINT p2,POINT p0){
return ((p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y));
}
bool online(SEGMENT l,POINT p){///判斷點是否在線段上
return ((multiply(l.e,p,l.s) == 0)&&(((p.x-l.s.x)*(p.x-l.e.x))<= 0)&&(((p.y-l.s.y)*(p.y-l.e.y)) <= 0));
}
bool intersect(SEGMENT u,SEGMENT v){///兩線段相交(包括端點),返回true
return ((max(u.s.x,u.e.x) >= min(v.s.x,v.e.x))&&
(max(v.s.x,v.e.x) >= min(u.s.x,u.e.x))&&
(max(u.s.y,u.e.y) >= min(v.s.y,v.e.y))&&
(max(v.s.y,v.e.y) >= min(u.s.y,u.e.y))&&
(multiply(v.s,u.e,u.s)*multiply(u.e,v.e,u.s) >= 0)&&
(multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s) >= 0));
}
bool intersect_a(SEGMENT u,SEGMENT v){///兩線段相交(不包括端點)
return ((intersect(u,v))&&
!online(u,v.s)&&
!online(u,v.e)&&
!online(v,u.e)&&
!online(v,u.s));
}
int lineintersect(LINE l1,LINE l2,POINT &p){///求兩直線交點,有交點返回1和交點,沒有返回0,重合返回2
double d = l1.a*l2.b-l2.a*l1.b;
double d2 = l1.a*l2.c-l2.a*l1.c;
double d3 = l1.b*l2.c-l2.b*l1.c;
if(fabs(d) < EP&&fabs(d2) < EP&&fabs(d3) < EP)return 2;
p.x = (l2.c*l1.b-l1.c*l2.b)/d;
p.y = (l2.a*l1.c-l1.a*l2.c)/d;
if(fabs(d) < EP)return 0;
return 1;
}
double point_dis(POINT a,POINT b){///求兩點距離
return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
}
///************************************************************************************************************************************
POINT point[60];
int n;
int ans;
bool vis[60];
int turn[60];
bool cmp(POINT a,POINT b){
if(a.y == b.y)return a.x < b.x;
else return a.y < b.y;
}
double dis(POINT a,POINT b){
double x = a.x - b.x;
double y = a.y - b.y;
return sqrt(x*x+y*y);
}
void dfs(POINT pre,POINT now,int t){
vis[now.id] = 1;
turn[t] = now.id;
double mul = -2;
int next;
double disa = dis(pre,now);
double last_dis;
for(int i = 0;i < n;i ++){
if(vis[point[i].id] == 0){
double disb = dis(now,point[i]);
POINT tt(point[i].x - (now.x - pre.x),point[i].y - (now.y - pre.y));
double tmp = dotmultiply(tt,now,pre)/(disa*disb);
if(fabs(tmp - mul) < EP){
if(disb < last_dis){
next = i;
last_dis = disb;
}
}
else if(tmp > mul){
mul = tmp;
next = i;
last_dis = disb;
}
}
}
if(mul != -2){
dfs(now,point[next],t+1);
}
}
int main(){
//freopen("in.txt","r",stdin);
int T;
cin>>T;
while(T --){
cin>>n;
for(int i = 0;i < n;i ++){
int a,b,c;
cin>>a>>b>>c;
point[i].x = b;
point[i].y = c;
point[i].id = i+1;
}
memset(vis,0,sizeof(vis));
sort(point,point+n,cmp);
dfs((POINT){0,point[0].y},point[0],1);
cout<<n;
for(int i = 1;i <= n;i ++){
cout<<' '<<turn[i];
}
cout<<endl;
}
return 0;
}