您的位置:首页 > 其它

POJ 1696 Space Ant

2011-08-10 17:52 274 查看
题目大意求一旋转向内的连线,可以想象成蜗牛的壳

不得不说这个我弄的狠纠结,一开是用的Graham,带上模板,一WA到死,怒了,代码全删了,自己看过包裹法,又认真看了遍叉积,点积,自己写了个只用叉积的算法。

算法思路:

step 1: 第一次取y最小,y相等取x最小的点。p0

step 2: 每次取第一个未标记的点pk,尝试拓展 p0-pk ,若发现存在pi 使得 p0-pi 在p0-pk 的左边(他们的叉积 < 0),则 k = i ;

step 3: 重复执行step 2,直到取得所有点

参考代码:

HOJ 1696

struct POINT {
int x,y;
int idx;
bool mark;
POINT(int i,int a,int b) {
idx=i;x=a;y=b;mark=false;
}
POINT(){}
}p[MAXN],res[MAXN];

int n,idx;

inline double multiply(POINT o,POINT s,POINT e) {
return ((s.x - o.x) * (e.y - o.y) - (s.y - o.y) * (e.x - o.x));
}

void ground() {
int cnt = 0;
for(int i = 1;i<n;i++) {
if(p[i].y < p[0].y ||
((p[i].y == p[0].y) &&
(p[i].x < p[0].x)))
swap(p[0],p[i]);
}
res[cnt++] = p[0];
p[0].mark = true;
while(cnt < n) {
int k = 0;
for(int i = 0;i<n;i++) {
if(!p[i].mark) {
k = i;
break;
}
}
for(int i = k + 1;i<n;i++) {
if(!p[i].mark) {
if(multiply(res[cnt-1],p[k],p[i]) < 0)
k = i;
}
}
res[cnt++] = p[k];
p[k].mark = true;
}
}

void init() {
SCF(n);
int id,a,b;
F(i,n) {
SCFT(id,a,b);
p[i] = POINT(id,a,b);
}
ground();
PCF(n);
F(i,n) printf(" %d",res[i].idx);
puts("");
}

int main() {
FOPEN;
int cse;SCF(cse);
while(cse --) {
init();
}
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: