| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
求大神帮忙看下,TLE啊,用扫描法求凸包,和别人的代码差不多,别人的代码跑110ms,我的却超时!!改了好多地方,还是这结果。这里附上我的代码和别人的代码。我的代码(TLE)呜呜~~~~(>_<)~~~~
#include<cstdio>
#include<iostream>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
#define N 50005
using namespace std;
struct point{
int x,y;
}pt[N];
int convex[N];
int n,k;
int xmult(point a,point b,point c){
return ((b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y));
}
int dist(point a,point b){
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
bool cmp(point a,point b)
{
if(xmult(pt[0],a,b)>0||(xmult(pt[0],a,b)==0&&dist(a,pt[0])<dist(b,pt[0])))return true;
return false;
}
bool left(int a,int b,int c){
if(xmult(pt[a],pt[b],pt[c])>=0)return true;
return false;
}
int max(int a,int b){
return a>b?a:b;
}
void swap(int a,int b){
int temp;
temp=pt[a].x;
pt[a].x=pt[b].x;
pt[b].x=temp;
temp=pt[a].y;
pt[a].y=pt[b].y;
pt[b].y=temp;
}
int main()
{
//freopen("in.txt","r",stdin);
int t,ans,i,j;
while(scanf("%d",&n)!=EOF){
k=t=ans=0;
for(i=0;i<n;i++){
scanf("%d %d",&pt[i].x,&pt[i].y);
if(pt[i].x<pt[k].x)
k=i;
else if(pt[i].x==pt[k].x&&pt[i].y<pt[k].y)
k=i;
}
if(k){
swap(k,0);
}
sort(pt+1,pt+n,cmp);
convex[t++]=0;
convex[t++]=1;
convex[t++]=2;
for(i=3;i<n;){
if(left(convex[i-2],convex[i-1],i))
convex[t++]=i++;
else --t;
}
for(i=0;i<t;i++)
for(j=i+1;j<t;j++)
ans=max(ans,dist(pt[i],pt[j]));
printf("%d\n",ans);
}
return 0;
}
下面是别人的代码(110ms):
#include<iostream>
#include<cmath>
#include<string>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;
const double PI=acos(-1);
const int N=50005;
struct node
{
int x,y;
}mem[N];
int used_point[N];
int dist(int i,int j)//求两点距离平方
{
return (mem[i].x-mem[j].x)*(mem[i].x-mem[j].x)
+(mem[i].y-mem[j].y)*(mem[i].y-mem[j].y);
}
bool cmp(node l1,node l2)//叉积排序 如果相等 近的优先
{
if((l1.x-mem[0].x)*(l2.y-mem[0].y)==(l2.x-mem[0].x)*(l1.y-mem[0].y))
return ((l1.x-mem[0].x)*(l1.x-mem[0].x)+(l1.y-mem[0].y)*(l1.y-mem[0].y))<
((mem[0].x-l2.x)*(mem[0].x-l2.x)+(mem[0].y-l2.y)*(mem[0].y-l2.y));
return (l1.x-mem[0].x)*(l2.y-mem[0].y)>(l2.x-mem[0].x)*(l1.y-mem[0].y);
}
bool Left_turn(int i,int j,int l)//判断是否左转
{
int x1=mem[j].x-mem[i].x;
int y1=mem[j].y-mem[i].y;
int x2=mem[l].x-mem[j].x;
int y2=mem[l].y-mem[j].y;
if(x1*y2>x2*y1)//如果左转 true (这种情况为不要直线上多余的点 如果想要应用 >=)
return true;
return false;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int k=0;
for(int i=0;i<n;++i)
{
scanf("%d %d",&mem[i].x,&mem[i].y);
if(mem[i].y<mem[k].y||(mem[i].y==mem[k].y&&mem[i].x<mem[k].x))
k=i;
}
if(k!=0)
{
swap(mem[0].x,mem[k].x);
swap(mem[0].y,mem[k].y);
}
sort(mem+1,mem+n,cmp);
int I=0;
used_point[I++]=0;
used_point[I++]=1;
used_point[I++]=2;
for(int i=3;i<n;)
{
if(I<2||Left_turn(used_point[I-2],used_point[I-1],i))//是左转则入栈加一 (I<2)的情况是对于开始就有直线又不要直线上多余点的情况,
//防止越界。如果直线上多余的点也要则可不写,但会有多余的点使得效率低
used_point[I++]=i++;
else//否则出栈
--I;
}
used_point[I]=used_point[0];
int ans=0;
for(int i=0;i<I;++i)
{
for(int j=i+1;j<I;++j)
{
ans=max(ans,dist(used_point[i],used_point[j]));//枚举最大距离平方
}
}
printf("%d\n",ans);
}
return 0;
}
Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator