HDU 5738 Eureka(map瞎搞)

来源:互联网 发布:如何成为一个网络作家 编辑:程序博客网 时间:2024/06/05 11:04

http://acm.hdu.edu.cn/showproblem.php?pid=5738
题意:让你求集合的数量,在这个集合里有一对点,然后其余所有点,都在这两点的线段上。


题解:总的来说就是求共线问题,为了不重复计算,我们枚举i的时候,只考虑从i+1到n的点,考虑共线,就要进行极角排序,但是可能会有精度误差,如果用double的话,就会GG,所以我选择了map存pair<a/gcd(a,b),b/gcd(a,b)>,然后一定不能忘记的是,必须把斜率的第一维都统一到正数,为什么呢,因为对于(0,0)来说,(1,1)和(-1,-1)是共线的但是不统一的话就不一样了,然后我犯了个很大的错误,就是第一维是0的时候,应该把第二维小于0的统一到正数QAQ,这里错了好久,还有就是重复点的处理,因为如果有重复点,那么斜率就是<0,0>,但是它其实又是和其他所有点都共线,这时候就需要把这个当前基准的这个点重复的点,就记录,然后最后计算的时候,加进去就好了, 然后对于一个斜率,每加入一个点,就考虑必选这个点,和必选基准点,然后这个斜率上还有x个点,那就是可选可不选,加上y个重复点,也是可选可不选,就每次都加上2x+y,最后考虑不选这些点,只选重复点,重复点有y个,那么就是加上2y1


代码:

#include <map>#include <set>#include <stack>#include <queue>#include <cmath>#include <string>#include <vector>#include <cstdio>#include <cctype>#include <cstring>#include <sstream>#include <cstdlib>#include <iostream>#include <algorithm>#pragma comment(linker,"/STACK:102400000,102400000")using namespace std;#define   MAX           1005#define   MAXN          1000005#define   maxnode       15#define   sigma_size    30#define   lson          l,m,rt<<1#define   rson          m+1,r,rt<<1|1#define   lrt           rt<<1#define   rrt           rt<<1|1#define   middle        int m=(r+l)>>1#define   LL            long long#define   ull           unsigned long long#define   mem(x,v)      memset(x,v,sizeof(x))#define   lowbit(x)     (x&-x)#define   pii           pair<int,int>#define   bits(a)       __builtin_popcount(a)#define   mk            make_pair#define   limit         10000//const int    prime = 999983;const int    INF   = 0x3f3f3f3f;const LL     INFF  = 0x3f3f;const double pi    = acos(-1.0);const double inf   = 1e18;const double eps   = 1e-8;const LL    mod    = 1e9+7;const ull    mx    = 133333331;/*****************************************************/inline void RI(int &x) {      char c;      while((c=getchar())<'0' || c>'9');      x=c-'0';      while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0'; }/*****************************************************/int x[MAX],y[MAX];struct PP{    int x,y;}u;map<pii,int> ma;struct Node{    LL dis;    int x,y;    bool operator < (const Node&a)const{        return dis<a.dis;    }}p[MAX];LL fact[1005];void init(){    fact[0]=1;    for(int i=1;i<=1000;i++) fact[i]=fact[i-1]*2%mod;}int gcd(int a,int b){    if(!b) return a;    return gcd(b,a%b);}int main(){    //freopen("in.txt","r",stdin);    int t;    cin>>t;    //cout<<fabs(atan2(2,1)-atan2(-2,-1))<<endl;    init();    while(t--){        int n;        cin>>n;        for(int i=0;i<n;i++){            scanf("%d%d",&x[i],&y[i]);            //x[i]=y[i]=0;        }        LL ans=0;        for(int i=0;i<n;i++){            int tot=0;            int num=0;            for(int j=i+1;j<n;j++){                //if(i==j) continue;                if(x[i]==x[j]&&y[i]==y[j]){                    num++;                    continue;                }                int flag=1;                if(x[j]-x[i]<0||(x[j]-x[i]==0&&y[j]-y[i]<0)) flag=-1;                p[tot++]=(Node){((LL)x[j]-x[i])*((LL)x[j]-x[i])+((LL)y[j]-y[i])*((LL)y[j]-y[i]),(x[j]-x[i])*flag,(y[j]-y[i])*flag};            }            sort(p,p+tot);            ma.clear();            for(int j=0;j<tot;j++){                int k=gcd(abs(p[j].x),abs(p[j].y));                ans+=fact[ma[mk(p[j].x/k,p[j].y/k)]+num];                ma[mk(p[j].x/k,p[j].y/k)]++;                if(ans>=mod) ans-=mod;            }            ans+=((fact[num]-1+mod)%mod);            if(ans>=mod) ans-=mod;        }        cout<<ans<<endl;    }    return 0;}
0 0
原创粉丝点击