[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 }
Orz mxh1999

 

你可能感兴趣的:(2008)