【hdu 5738】Eureka

来源:互联网 发布:linux 虚拟主机配置 编辑:程序博客网 时间:2024/06/04 21:05

题解:

什么是最好的集合?至少有两个点是共线的。也考虑到了这一点,但是数集合的时候,数得并不完美。

代码如下:

#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <ctime>#include <iostream>#include <algorithm>#include <string>#include <vector>#include <deque>#include <list>#include <set>#include <map>#include <stack>#include <queue>#include <numeric>#include <iomanip>#include <bitset>#include <sstream>#include <fstream>#include <limits.h>#define debug "output for debug\n"#define pi (acos(-1.0))#define eps (1e-6)#define inf (1<<28)#define sqr(x) (x) * (x)#define mod 1000000007using namespace std;typedef long long ll;typedef unsigned long long ULL;typedef pair<ll,ll> p;map<p,ll> m;struct point{    ll x,y;}a[1005];ll gcd(ll a,ll b){    return b?gcd(b,a%b):a;}bool cmp(point a,point b){    if(a.x==b.x)        return a.y<b.y;    return a.x<b.x;}long long qpow(long long a, long long b){    if(b < 0) return 0;    long long ret = 1;    a %= mod;    for (; b; b >>= 1, a = (a * a) % mod)        if (b & 1)            ret = (ret * a) % mod;    return ret;}int main(){    ll i,j,k,n,t;    scanf("%I64d",&t);    while(t--)    {        scanf("%I64d",&n);        for(i=0;i<n;i++)            scanf("%I64d%I64d",&a[i].x,&a[i].y);        sort(a,a+n,cmp);        ll ans=0;        ll res;        for(i=0;i<n;i++)        {            m.clear();            res = 1;            for(j=i+1;j<n;j++)            {                if(a[j].x==a[i].x&&a[j].y==a[i].y)                {                    res++;                }                else {                ll dx=a[j].x-a[i].x;                ll dy=a[j].y-a[i].y;                ll d=gcd(dx,dy);                if(d!=0)                {                    dx=dx/d;                    dy=dy/d;                }                m[make_pair(dx,dy)]++;                }             }             //cout << "res  = "<< res<<endl;            if(res>1) {ans=ans+(qpow(2,res-1)-1);ans%=mod;            }           // cout << "ans =    "<<ans<<endl;            map<p,ll>::iterator it;            for(it=m.begin();it!=m.end();it++)            {                k=it->second;                ans=ans+(qpow(2,res-1)*(qpow(2,k)-1)%mod);                ans%=mod;            }        }        printf("%I64d\n",ans);    }    return 0;}

学习点:

  1. 用pair+map+gcd保存斜率
  2. 数点的时候每个点有两种情况(出现,不出现),如果与第i个点相同的有m个,那么对于只有相同点时,ans=pqow(2,m)-1【减去都消失的情况】;一次共线的有n个,ans =pqow(2,m)*(pqow(2,n)-1)。

交hdu的时候CE了,好几发,为什么呢?刚开始吧快速幂的函数名与pow()重名了。

0 0
原创粉丝点击