zoukankan      html  css  js  c++  java
  • 随机的点


    描述 Description
    陶陶为了给一道平面几何题出数据,需要产生 N 个点(x[i],y[i])。已知x,y是由伪随机函数顺序产生,即:
    X[i+1] = (X[i]*Ax+Bx+i) mod Cx (X[1], Ax,Bx,Cx 是事先给定的)
    Y[i+1] = (Y[i]*Ay+By+i) mod Cy (Y[1], Ay,By,Cy 是事先给定的)

    这样,就可以快速连续产生很多点坐标(X[i], Y[i])。
    不幸的是,这样产生的点有可能有相同的,虽然这种几率很少,但严谨的陶陶不允许这种事发生。陶陶要求你帮助他解决最少要产生前多少项时,正好有 N 个不相同的点。



    输入格式 Input Format
    第一行。一个整数 N .
    第二行:4个整数 X[1]、 Ax、Bx、Cx .
    第三行:4个整数 Y[1]、 Ay、By、Cy .


    输出格式 Output Format
    一个整数 M 。表示最少要连续产生 M 个点,正好有 N 个不相同的点。数据保证有答案。


    样例输入 Sample Input
    21
    2 4 3 6
    5 2 3 13


    样例输出 Sample Output
    24


    时间限制 Time Limitation
    1s


    注释 Hint
    1<=N<=1,000,000, 其它所有数据都在[0...1,000,000,000]范围内。


    来源 Source
    经典问题

          思路:对于刚学hash的焫鷄,书上给的模板是求一个数x的查找。但这道题是求一个坐标,有两个数怎么办呢??仔细一想回发现因为你用hash存的就是一个位置,所以你可以直接让(x+y)在取模那个大的质数,然后其他操作就和普通的hash一样了。然后你高高兴兴的把程序交上去。。。(超时???)听century一说,你必须的让x和y乘一个大数相加在取模,这是为什么呢??因为在你没有乘一个大数的时候刚开始的x,y相加取模的值也不会改变,所以你前面存的点就过于密集,导致查找时时间过慢,如果你乘上一个大数,就会使这个hash变得散,所以时间复杂度就大大降低了。然后你又兴冲冲的交了上去。。。。。(wrong answer???),你会发现x1,y1为零的点你的答案都加了一??这又是为什么呢??因为你刚开始给这个结构体付的值为0,所以刚开始他就判断x1,y1为零的点已经存在了,所以你只需手动付一下x的值为-1就好了

        

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    using namespace std;
    const int maxprime=2323237;
    const int step=7;
    struct shadow
    {
        long long x,y,num;
    }hash[maxprime+5];
    int q,w;
    int find(long long g,long long k)
    {
        int temp=(g*499979+k*299993)%maxprime;
        while((hash[temp].num)&&(hash[temp].x!=g||hash[temp].y!=k))
        {
            temp+=step;
            if(temp>=maxprime)
                temp-=maxprime;
        } 
        return temp;
    }
    int ans=0,h=0;
    void insert(long long g,long long k)
    {
        int now=find(g,k);
        if(hash[now].y==k&&hash[now].x==g)
            return;
        else
        {
            h++;
            hash[now].x=g;
            hash[now].y=k;
            hash[now].num=1;
        }
    }
    int main()
    {
        //freopen("add.out","w",stdout);
        memset(hash,0,sizeof(hash));
        for(int i=0;i<=2323237+4;i++)
            hash[i].x=-1;
        int n;
        cin>>n;
        int x1,a1,b1,c1;
        cin>>x1>>a1>>b1>>c1;
        int y1,a2,b2,c2;
        cin>>y1>>a2>>b2>>c2;
        long long g=x1,k=y1;
        for(int i=1;;i++)
        {
            insert(g,k);
            g=(g*a1+b1+i)%c1;
            k=(k*a2+b2+i)%c2;
            //cout<<g<<' '<<k<<endl;
            ans++;
            if(h==n)
            {
                cout<<ans<<endl;
                break;
            }
        }
        return 0;
    }
    <( ̄ ﹌  ̄)>
  • 相关阅读:
    css之深入理解padding
    css布局大杂烩
    css深入理解margin
    css之深入理解border
    css样式画各种图形
    css Sprite雪碧图
    JVM,JRE,JDK
    JAVA 遍历数组
    JAVA 得到数组的长度
    大一对软件工程
  • 原文地址:https://www.cnblogs.com/lcyhaha/p/7470225.html
Copyright © 2011-2022 走看看