zoukankan      html  css  js  c++  java
  • [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='
    ')
    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
  • 相关阅读:
    用队列打印杨辉三角
    mysql允许远程连接
    window文件恢复工具
    android 虚拟机没有sd卡
    StringUtils 的填充方法
    plsql 中出现 Dynamic Performance Tables not accessible 问题解决
    oracle数据库服务介绍
    遮罩的使用
    <pre>标签
    总结五个小技巧定位数据库性能问题
  • 原文地址:https://www.cnblogs.com/dyllalala/p/3899692.html
Copyright © 2011-2022 走看看