Hdu 4517 小小明系列故事——游戏的烦恼

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4517

第一种解法:

遍历求解。num[i][j]代表i行j列之前一共有多少个'×'。然后再面积夹击求解x*y、y*x是否满足,x==y只需要判断一次。

这种方法提交用C++,不要用G++,否则会超时。

 

#include <iostream>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <math.h>

#include <algorithm>

#include <stack>

#include <queue>

using namespace std;



int map[2005][2005];

int num[2005][2005];



int main()

{

#ifndef ONLINE_JUDGE

    freopen("in.txt","r",stdin);

#endif

    int n,m,x,y;

    while(scanf(" %d %d",&n,&m)!=EOF)

    {

        if(n+m == 0) break;

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

        {

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

            {

                num[i][j] = 0;

            }

        }



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

        getchar();

        for(int i=1; i<=n; i++)

        {

            for(int j=1; j<=m; j++)

            {

                char c;

                scanf("%c",&c);

                if(c == '*')

                {

                    map[i][j] = 1;

                }

                else

                {

                    map[i][j] = 0;

                }

            }

            getchar();

        }

        for(int i=1; i<=n; i++)

        {

            for(int j=1; j<=m; j++)

            {

                if(map[i][j] == 1)

                {

                    num[i][j] = num[i-1][j] + num[i][j-1] - num[i-1][j-1] + 1;

                }

                else

                {

                    num[i][j] = num[i-1][j] + num[i][j-1] - num[i-1][j-1];

                }

            }

        }

        int ans = 0;

        int size = x*y;

        for(int i=x; i<=n; i++)

        {

            for(int j=y; j<=m; j++)

            {

                //满足x*y的摆放位置

                if(num[i][j] - num[i-x][j] - num[i][j-y] + num[i-x][j-y] == size)

                {

                    ans++;

                }

            }

        }

        if(x!=y)

        {

            for(int i=y; i<=n; i++)

            {

                for(int j=x; j<=m; j++)

                {

                    //满足x*y的摆放位置

                    if(num[i][j] - num[i-y][j] - num[i][j-x] + num[i-y][j-x] == size)

                    {

                        ans++;

                    }

                }

            }

        }

        printf("%d\n",ans);

    }

    return 0;

}

 

第二种方法:

二维DP,但是会MLE。

 

#include <iostream>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <math.h>

#include <algorithm>

#include <stack>

#include <queue>

using namespace std;



int map[2005][2005];

int h[2005][2005];

int l[2005][2005];

int l2[2005][2005];



int main()

{

#ifndef ONLINE_JUDGE

    freopen("in.txt","r",stdin);

#endif

    int n,m,x,y;

    while(scanf(" %d %d",&n,&m)!=EOF)

    {

        if(n+m == 0) break;

        memset(h,0,sizeof(h));

        memset(l,0,sizeof(l));

        memset(l2,0,sizeof(l2));

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

        getchar();

        for(int i=1; i<=n; i++)

        {

            for(int j=1; j<=m; j++)

            {

                char c;

                scanf("%c",&c);

                if(c == '*')

                    map[i][j] = 1;

                else

                    map[i][j] = 0;

            }

            getchar();

        }

        int ans = 0;

        for(int i=1; i<=n; i++)

        {

            for(int j=1; j<=m; j++)

            {

                if(map[i][j] == 1)

                {

                    h[i][j] = h[i-1][j] + 1;

                    if(h[i][j]>=x)

                        l[i][j] = l[i][j-1] + 1;

                    else

                        l[i][j] = 0;

                    if(h[i][j]>=y)

                        l2[i][j] = l2[i][j-1] + 1;

                    else

                        l2[i][j] = 0;

                    if(h[i][j]>=x && l[i][j]>=y)

                        ans++;

                    if(h[i][j]>=y && l2[i][j]>=x && x!=y)

                        ans++;

                }

                else

                {

                    h[i][j] = l[i][j] = l2[i][j] = 0;

                }

            }

        }

        printf("%d\n",ans);

    }

    return 0;

}


 


第三种:

改成滚动数组,变成一维DP。

 

#include <iostream>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <math.h>

#include <algorithm>

#include <stack>

#include <queue>

using namespace std;



int map[2005][2005];

int h[2005];

int l[2005];

int l2[2005];



int main()

{

#ifndef ONLINE_JUDGE

    freopen("in.txt","r",stdin);

#endif

    int n,m,x,y;

    while(scanf(" %d %d",&n,&m)!=EOF)

    {

        if(n+m == 0) break;

        memset(h,0,sizeof(h));

        memset(l,0,sizeof(l));

        memset(l2,0,sizeof(l2));



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

        getchar();

        for(int i=1; i<=n; i++)

        {

            for(int j=1; j<=m; j++)

            {

                char c;

                scanf("%c",&c);

                if(c == '*')

                    map[i][j] = 1;

                else

                    map[i][j] = 0;

            }

            getchar();

        }

        int ans = 0;

        for(int i=1; i<=n; i++)

        {

            for(int j=1; j<=m; j++)

            {

                if(map[i][j] == 1)

                {

                    h[j] = h[j] + 1;

                    if(h[j]>=x)

                        l[j] = l[j-1] + 1;

                    else

                        l[j] = 0;

                    if(h[j]>=y)

                        l2[j] = l2[j-1] + 1;

                    if(h[j]>=x && l[j]>=y)

                        ans++;

                    if(h[j]>=y && l2[j]>=x && x!=y)

                        ans++;

                }

                else

                {

                    h[j] = l[j] = l2[j] = 0;

                }

            }

        }

        printf("%d\n",ans);

    }

    return 0;

}


 

 

 

你可能感兴趣的:(HDU)