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

来源:互联网 发布:不知为不知是知也的知 编辑:程序博客网 时间:2024/06/03 11:45

题目连接: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;}