[POI 2008][BZOJ 1132]Tro
这题我真是无能为力了
这题的做法还是挺简单的
枚举左下角的点做为原点,把其余点按极角排序 PS.是作为原点,如枚举到 k 时,对于所有 p[i] (包括p[k]) p[i]-=p[k] (此处为向量减法)
排序后满足 i<j 的两个向量 p[i] 和 p[j] 的叉积都是正数了
ΣΣp[i]×p[j] = ΣΣ(p[i].x*p[j].y-p[i].y*p[j].x) = Σ(p[i].x*Σp[j].y)-Σ(p[i].y*Σp[j].x)
计算叉积和的复杂度就从 O(n2) 降为了 O(n)
再加上枚举和排序的复杂度,总复杂度就是 O(n2logn)
但是我的代码似乎被 BZOJ 讨厌了%>_<%
本地测都是 A 的,校内 OJ 也 A 了,但BZOJ一交上去秒 WA 啊,55555555
求大爷指导……
这是错误的代码,求教做人
1 #include <cstdio> 2 #include <algorithm> 3 const int size=5000; 4 typedef struct point vector; 5 typedef long long llint; 6 7 namespace IOspace 8 { 9 inline int getint() 10 { 11 register int num=0; 12 register char ch; 13 do ch=getchar(); while (ch<'0' || ch>'9'); 14 do num=num*10+ch-'0', ch=getchar(); while (ch>='0' && ch<='9'); 15 return num; 16 } 17 inline void putint(llint num, char ch='\n') 18 { 19 char stack[20]; 20 register int top=0; 21 if (num==0) stack[top=1]='0'; 22 for ( ;num;num/=10) stack[++top]=num%10+'0'; 23 for ( ;top;top--) putchar(stack[top]); 24 if (ch) putchar(ch); 25 } 26 } 27 28 struct point 29 { 30 llint x, y; 31 inline point() {} 32 inline point(llint _x, llint _y):x(_x), y(_y) {} 33 inline vector & operator += (vector v) {x+=v.x; y+=v.y; return *this;} 34 inline vector & operator -= (vector v) {x-=v.x; y-=v.y; return *this;} 35 }; 36 point p[size]; 37 inline llint operator * (vector a, vector b) {return a.x*b.y-a.y*b.x;} 38 inline bool operator < (point a, point b) {return a*b>0;} 39 inline void swap(point & a, point & b) {point t=a; a=b; b=t;} 40 41 int N; 42 inline llint count(int); 43 44 int main() 45 { 46 llint ans=0; 47 48 N=IOspace::getint(); 49 for (int i=1;i<=N;i++) p[i].x=IOspace::getint(), p[i].y=IOspace::getint(); 50 51 for (int i=N;i>=1;i--) ans+=count(i); 52 53 bool b=ans&1LL; 54 IOspace::putint(ans>>1LL, '.'); 55 IOspace::putint(b?5:0); 56 57 return 0; 58 } 59 inline llint count(int n) 60 { 61 llint ret=0; 62 63 int k=1; 64 for (int i=1;i<=n;i++) 65 if (p[i].x<p[k].x || p[i].x==p[k].x && p[i].y<p[k].y) 66 k=i; 67 swap(p[k], p[n]); 68 69 for (int i=1;i<=n;i++) p[i]-=p[n]; 70 71 std::sort(p+1, p+n); 72 73 vector s(0, 0); 74 for (int i=1;i<=n;i++) 75 { 76 ret+=s*p[i]; 77 s+=p[i]; 78 } 79 80 return ret; 81 }
我再把正确的放上来,帮助理解题解:
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 using namespace std; 5 6 #define maxn 30010 7 typedef long long ll; 8 struct xllend3 9 { 10 int x,y; 11 } orz[maxn]; 12 13 int n,m; 14 ll ans; 15 16 bool cmp(const xllend3 &a,const xllend3 &b) 17 { 18 return a.x*b.y>a.y*b.x; 19 } 20 ll orzhzw(int n) 21 { 22 int i=0; 23 for (int j=0;j<n;j++) 24 if (orz[j].x<orz[i].x||(orz[j].x==orz[i].x && orz[j].y<orz[i].y)) 25 i=j; 26 swap(orz[i],orz[n-1]); 27 for (int i=0;i<n-1;i++) 28 orz[i].x-=orz[n-1].x,orz[i].y-=orz[n-1].y; 29 sort(orz,orz+n-1,cmp); 30 ll gui=0; 31 ll sx=0,sy=0; 32 for (int i=n-2;i>=0;i--) 33 { 34 gui+=(ll)orz[i].x*sy-(ll)orz[i].y*sx; 35 sx+=orz[i].x; 36 sy+=orz[i].y; 37 } 38 return gui; 39 } 40 41 int main() 42 { 43 scanf("%d",&n); 44 for (int i=0;i<n;i++) scanf("%d%d",&orz[i].x,&orz[i].y); 45 for (int i=n;i>2;i--) ans+=orzhzw(i); 46 cout<<ans/2; 47 if (ans&1) cout<<".5"<<endl;else cout<<".0"<<endl; 48 return 0; 49 }