【 HDU

As an eligible Ingress Resistance Agent you should know your power source, the Exotic Matter.
We call it XM, which is the driving force behind all of our actions in Ingress.
XM allows us to construct items through hacking portals, to attack enemy portals, make links and create fields.

We try to collect XM from the ground. XM concentration come from location based services, meaning that areas with a lot of foot traffic have higher amounts versus places that don't.
You can collect XM by moving through those areas.
The XM will be automatically harvested by your Scanner when it is within your interaction circle/range.

Alice decides to select a location such that she can collect XM as much as possible.
To simplify the problem, we consider the city as a grid map with size `n*m' numbered from (0,0)(0,0) to (n1,m1)(n−1,m−1) .
The XM concentration inside the block (i,j)(i,j) is p(i,j)p(i,j) .
The radius of your interaction circle is rr .
We can assume that XM of the block (i,j)(i,j) are located in the centre of this block.
The distance between two blocks is the Euclidean distance between their centres.

Alice stands in the centre of one block and collects the XM.
For each block with the distance d smaller than r to Alice, and whose XM concertation is p(i,j)p(i,j) , Alice's scanner can collects p(i,j)/(1+d)p(i,j)/(1+d) XM from it.

Help Alice to determine the maximum XM which she can collect once he stands in the centre of one block.

InputThere are multiple cases.
For each case, the first line consists two integers n,m (1n,m500)n,m (1≤n,m≤500) and one float-point number r (0r300)r (0≤r≤300) .
Each of the following nn line consists mm non-negative float-point numbers corresponding to the XM concentrations inside each blocks.
OutputFor each case, output the maximum XM which Alice can collect in one line.

Your answers should be rounded to three decimal places.Sample Input

3 3 1
1 3 6
7 9 4
2 8 1
3 3 2
1 3 6
7 9 4
2 8 1
5 5 1.5
4 3 2 9 1 
3 4 3 2 8
9 4 3 2 1
2 3 0 1 2
6 3 4 3 1

Sample Output

9.000
24.142
17.956

SOLUTION:
从暴力入手,某一个点的答案有许多点的值汇集而成的
,再仔细的想想的话,像是某些点经过一些坐标的变换能到的一个相同的点,从而后成的这个点的
答案,好像有点fft的感觉。。

 

CODE:


#include<cstdio>

#include<cmath>

#include<algorithm>

using namespace std;



const double PI=acos(-1);

struct C
{

    double x,y;

    C(double _x=0,double _y=0)
    {

        x=_x;
        y=_y;

    }

    C operator+(const C &p)
    {

        return C(x+p.x,y+p.y);

    }

    C operator-(const C &p)
    {

        return C(x-p.x,y-p.y);

    }

    C operator*(const C &p)
    {

        return C(x*p.x-y*p.y,x*p.y+y*p.x);

    }

};

void fft(C x[],int len,int on)
{

    for(int i=1,j=len/2; j<len-1; ++i)
    {

        if(i<j) swap(x[i],x[j]);

        int k=len>>1;

        while(j>=k)
        {

            j-=k;

            k>>=1;

        }

        if(j<k) j+=k;

    }

    for(int h=2; h<=len; h<<=1)
    {

        C wn(cos(-on*2*PI/h),sin(-on*2*PI/h));

        for(int j=0; j<len; j+=h)
        {

            C w(1,0);

            for(int k=j; k<j+h/2; ++k)
            {

                C u=x[k];

                C t=w*x[k+h/2];

                x[k]=u+t;

                x[k+h/2]=u-t;

                w=w*wn;

            }

        }

    }

    if(on==-1)
    {

        for(int i=0; i<len; ++i) x[i].x/=len;

    }

}



const int N=(1<<21);

C X1[N],X2[N];



double dis(int x,int y)
{

    return sqrt(x*x+y*y);

}



int main()
{

    int n,m;
    double r;

    while(~scanf("%d%d%lf",&n,&m,&r))
    {



        int R=ceil(r);

        int M=max(n+2*R,m+2*R);



        int len=1;

        while(len<=M*M) len<<=1;



        for(int i=0; i<len; ++i) X1[i]=X2[i]=C(0,0);

        for(int i=0; i<n; ++i)
        {

            for(int j=0; j<m; ++j)
            {

                int x;
                scanf("%d",&x);

                X1[i*M+j]=C(x,0);

            }

        }

        for(int i=-R; i<=R; ++i)
        {

            for(int j=-R; j<=R; ++j)
            {

                if(dis(i,j)<r) X2[(i+R)*M+j+R]=C(1.0/(dis(i,j)+1),0);

            }

        }

        fft(X1,len,1);

        fft(X2,len,1);

        for(int i=0; i<len; ++i) X1[i]=X1[i]*X2[i];

        fft(X1,len,-1);

        double ans=0;

        for(int i=0; i<n; ++i)
        {

            for(int j=0; j<m; ++j)
            {

                ans=max(ans,X1[(i+R)*M+j+R].x);

            }

        }

        printf("%.3f
",ans);

    }

    return 0;

}

  









原文地址:https://www.cnblogs.com/zhangbuang/p/11477707.html