POJ 3034 Whac-a-Mole

题目大意:

打地鼠游戏,n*n的矩阵,每一个整数点(x,y)都有一个鼠洞,某个老鼠在某个鼠洞出现的时间只有一秒。游戏者拿着锤子,锤子可以在任意一个整数点上(不一定在矩阵内)。游戏者每一秒可以将锤子从当前位置直线移动到下一位置(整数点)。两位置之间的距离不超过d。移动的直线路径穿过的(过整数点中心的)鼠洞如果有老鼠,都会被打晕。例如(0,0)移动到(0,3)。如果(0,1),(0,2)有老鼠出现就会被打晕。打晕一只老鼠得一分,求最大分数。


解题思路:

Dp[i][j][k]代表点(i,j)在第k秒最多可以得多少分。

它等于dp[x][y][k-1](点(x,y)为任意一个一秒内能到达(i,j)的点。)加上路径中打晕的地鼠数。求他们的最大值。



下面是代码:

#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <math.h>
#include <map>
#include <queue>
#include <stack>
#include <set>
#define maxn 100005
#define LL long long
#define ll __int64
#define eps 1e-4
#define INF 1e8
#define pi acos(-1.0)
#define mol 200907
using namespace std;
int min(int a,int b)
{
    if(a>b)a=b;
    return a;
}
int max(int a,int b)
{
    if(a<b)a=b;
    return a;
}
int dp[30][30][15],d,n,m;
bool vis[30][30][15];
int does(int x,int y,int t)
{
    int l=0,u=0;
    if(x-d>l)l=x-d;
    if(y-d>u)u=y-d;
    int r=n+10;
    int e=n+10;
    if(x+d+1<r)r=x+d+1;
    if(y+d+1<e)e=y+d+1;
    int max2=0,xadd,yadd,div,temp;
    for(;l<r;l++)
    {
        for(int ux=u;ux<e;ux++)
        {
            if(((l-x)*(l-x)+(ux-y)*(ux-y))<=d*d)
            {
                xadd=abs(l-x);
                yadd=abs(ux-y);
                div=__gcd(xadd,yadd);
                if(div!=0)
                {
                    xadd/=div;
                    yadd/=div;
                }
                else if(xadd==0)
                {
                    yadd=1;
                }
                else if(yadd==0)
                {
                    xadd=1;
                }
                if(l>x)xadd=-xadd;
                if(ux>y)yadd=-yadd;
                temp=dp[l][ux][t-1];
                for(int w=l,h=ux;w!=x||h!=y;w+=xadd,h+=yadd)
                {
                    if(vis[w][h][t])
                    {
                        temp++;
                    }
                }
                if(vis[x][y][t])temp++;
                max2=max(max2,temp);
            }
        }
    }
    return max2;
}
int main()
{
    while(scanf("%d%d%d",&n,&d,&m),n||d||m)
    {
        memset(vis,false,sizeof(vis));
        memset(dp,0,sizeof(dp));
        int x,y,t;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&x,&y,&t);
            vis[x+5][y+5][t]=true;
        }
        int max1=0;
        for(int k=1;k<=10;k++)
        {
            for(int i=0;i<n+10;i++)
            {
                for(int j=0;j<n+10;j++)
                {
                    dp[i][j][k]=does(i,j,k);
                    max1=max(max1,dp[i][j][k]);
                }
            }
        }
        printf("%d\n",max1);
    }
    return 0;
}


你可能感兴趣的:(dp,poj,刷题)