• UVALive 6886 Golf Bot FFT


    Golf Bot

    题目连接:

    http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=129724

    Description

    Do you like golf? I hate it. I hate golf so much that I
    decided to build the ultimate golf robot, a robot that
    will never miss a shot. I simply place it over the ball,
    choose the right direction and distance and, flawlessly,
    it will strike the ball across the air and into the hole.
    Golf will never be played again.
    Unfortunately, it doesn’t work as planned. So, here
    I am, standing in the green and preparing my first
    strike when I realize that the distance-selector knob
    built-in doesn’t have all the distance options! Not everything
    is lost, as I have 2 shots.
    Given my current robot, how many holes will I be
    able to complete in 2 strokes or less? The ball must be
    always on the right line between the tee and the hole.
    It isn’t allowed to overstep it and come back.

    Input

    The input file contains several test cases, each of them
    as described below.
    The first line has one integer: N, the number of
    different distances the Golf Bot can shoot. Each of
    the following N lines has one integer, ki
    , the distance
    marked in position i of the knob.
    Next line has one integer: M, the number of holes in this course. Each of the following M lines has
    one integer, dj , the distance from Golf Bot to hole j.
    Constraints:
    1 ≤ N, M ≤ 200 000
    1 ≤ ki
    , dj ≤ 200 000

    Output

    For each test case, you should output a single integer, the number of holes Golf Bot will be able to
    complete. Golf Bot cannot shoot over a hole on purpose and then shoot backwards.
    Sample Output Explanation
    Golf Bot can shoot 3 different distances (1, 3 and 5) and there are 6 holes in this course at distances
    2, 4, 5, 7, 8 and 9. Golf Bot will be able to put the ball in 4 of these:
    • The 1st hole, at distance 2, can be reached by striking two times a distance of 1.
    • The 2nd hole, at distance 4, can be reached by striking with strength 3 and then strength 1 (or
    vice-versa).
    • The 3rd hole can be reached with just one stroke of strength 5.
    • The 5th hole can be reached with two strikes of strengths 3 and 5.
    Holes 4 and 6 can never be reached

    Sample Input

    3
    1
    3
    5
    6
    2
    4
    5
    7
    8
    9

    Sample Output

    4

    Hint

    题意

    给你n个数,然后再给你一个数k,问这个数是否就是那n个数中的一个,或者说这个数可以由这n个数中的两个构成(可以是自己*2)

    题解:

    裸的不行的FFT,直接做就好了。

    代码

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int N = 1200040;
    const double pi = acos(-1.0);
    
    int len;
    
    struct Complex
    {
        double r,i;
        Complex(double r=0,double i=0):r(r),i(i) {};
        Complex operator+(const Complex &rhs)
        {
            return Complex(r + rhs.r,i + rhs.i);
        }
        Complex operator-(const Complex &rhs)
        {
            return Complex(r - rhs.r,i - rhs.i);
        }
        Complex operator*(const Complex &rhs)
        {
            return Complex(r*rhs.r - i*rhs.i,i*rhs.r + r*rhs.i);
        }
    } va[N],vb[N];
    
    void rader(Complex F[],int len) //len = 2^M,reverse F[i] with  F[j] j为i二进制反转
    {
        int j = len >> 1;
        for(int i = 1;i < len - 1;++i)
        {
            if(i < j) swap(F[i],F[j]);  // reverse
            int k = len>>1;
            while(j>=k)
            {
                j -= k;
                k >>= 1;
            }
            if(j < k) j += k;
        }
    }
    
    void FFT(Complex F[],int len,int t)
    {
        rader(F,len);
        for(int h=2;h<=len;h<<=1)
        {
            Complex wn(cos(-t*2*pi/h),sin(-t*2*pi/h));
            for(int j=0;j<len;j+=h)
            {
                Complex E(1,0); //旋转因子
                for(int k=j;k<j+h/2;++k)
                {
                    Complex u = F[k];
                    Complex v = E*F[k+h/2];
                    F[k] = u+v;
                    F[k+h/2] = u-v;
                    E=E*wn;
                }
            }
        }
        if(t==-1)   //IDFT
            for(int i=0;i<len;++i)
                F[i].r/=len;
    }
    
    void Conv(Complex a[],Complex b[],int len) //求卷积
    {
        FFT(a,len,1);
        FFT(b,len,1);
        for(int i=0;i<len;++i) a[i] = a[i]*b[i];
        FFT(a,len,-1);
    }
    int n;
    int a[N];
    long long num[N],sum[N];
    void solve()
    {
        memset(num,0,sizeof(num));
        memset(sum,0,sizeof(sum));
        memset(va,0,sizeof(va));
        memset(vb,0,sizeof(vb));
        int Mx = 0;
        for(int i=0;i<n;i++)
        {
            int x;scanf("%d",&a[i]);
            Mx = max(Mx,a[i]);
            num[a[i]]=1;
        }
        Mx*=2;
        len=1;
        while(len<=Mx+1)len*=2;
        sort(a,a+n);
        for(int i=0;i<=len;i++)
        {
            va[i].r=num[i];
            va[i].i=0;
            vb[i].r=va[i].r;
            vb[i].i=0;
        }
        Conv(va,vb,len);
        for(int i=0;i<len;i++)
            num[i]+=(long long)(va[i].r+0.5);
        int cnt = 0;
        int q;scanf("%d",&q);
        while(q--){
            int bbb;
            scanf("%d",&bbb);
            if(num[bbb])cnt++;
        }
        printf("%d
    ",cnt);
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF)solve();
        return 0;
    }
  • 相关阅读:
    OpenStack trove原理及配置实践
    [转]在首席架构师手里,应用架构如此设计
    Servlet入门(一),超级详细!!!看完就会!!!!
    Redis入门
    Linux笔记02—Linux进阶应用
    Linux笔记01—linux基础入门
    Linux笔记00—计算机概论
    Linux上安装jdk
    SpringBoot入门
    排查问题的五个步骤
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5677488.html
Copyright © 2020-2023  润新知