http://poj.org/problem?id=3034

n*n方阵 特定时间 特定位置有 moles 同一时间锤子可以 打一条直线上的moles

直线最大距离为 d 

根据时间 逐层更新数量

注意超出 d 范围的情况 和 锤子停留在方阵外的情况

代码及其注释:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<cmath>
#include<stack>
#include<algorithm>

using namespace std;

int sum[15][42][42];//时间 位置 记录最大值
int appear[15][42][42];//时间 位置 是否出现moles
int d;
int FindSum(int x,int y,int x1,int y1,int t)//在第 t 时间从(x.y)到(x1,y1) 可以多少moles
{
    if((x-x1)*(x-x1)+(y-y1)*(y-y1)>d*d)//如果超出范围 返回-1
    return -1;
    if(y>y1)
    {
        swap(y,y1);
        swap(x,x1);
    }
    int kx=x1-x;int ky=y1-y;
    int s=0;
    if(x==x1)
    {
        for(int j=y;j<=y1;++j)
        {
            if(appear[t][x][j]==1)
            ++s;
        }
        return s;
    }
    if(y==y1)
    {
        for(int i=min(x,x1);i<=max(x,x1);++i)
        {
            if(appear[t][i][y]==1)
            ++s;
        }
        return s;
    }
    if(appear[t][x][y]==1)
    ++s;
    if(appear[t][x1][y1]==1)
    ++s;
    if((abs(kx)==2&&(ky==4||ky==2))||((abs(kx)==2||abs(kx)==4)&&ky==2))
    {
        if(appear[t][(x+x1)/2][(y+y1)/2]==1)
        ++s;
        return s;
    }
    if(abs(kx)==3&&ky==3)
    {
        if((kx==3&&appear[t][x+1][y+1]==1)||(kx==-3&&appear[t][x-1][y+1]==1))
        ++s;
        if((kx==3&&appear[t][x+2][y+2]==1)||(kx==-3&&appear[t][x-2][y+2]==1))
        ++s;
        return s;
    }
    return s;
}
int main()
{

   int n,m;
   while(scanf("%d %d %d",&n,&d,&m)!=EOF)
   {
       if(n==0&&d==0&&m==0)
       break;
       memset(appear,0,sizeof(appear));
       int T=0;
       while(m--)
       {
           int x,y,t;
           scanf("%d %d %d",&x,&y,&t);
           T=max(T,t);
           appear[t][x+d][y+d]=1;
       }
       memset(sum,0,sizeof(sum));
       int ans=0;
       for(int t=1,k=1;t<=T;++t,k=k*10)
       {
           for(int x=0;x<n+2*d;++x)
           {
               for(int y=0;y<n+2*d;++y)
               {
                   for(int i=0;i<n+2*d;++i)
                   {
                       for(int j=0;j<n+2*d;++j)
                       {
                           int q=FindSum(x,y,i,j,t);
                           if(q==-1)//无法到达 不更新
                           continue;
                           sum[t+1][i][j]=max(sum[t+1][i][j],sum[t][x][y]+q);//更新
                           if(t==T)
                           ans=max(ans,sum[t+1][i][j]);//找最大值
                       }
                   }
               }
           }
       }
       printf("%d\n",ans);
   }
   return 0;
}

  

posted on 2012-07-20 14:19  夜->  阅读(209)  评论(0编辑  收藏  举报