zoukankan      html  css  js  c++  java
  • 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;
    }
    


  • 相关阅读:
    支付业务的数据库表的设计
    数据库设计的一些参考(来源网上的一些帖子,仅供作者本人参考)
    Delphi 10.2的 更新说明,所有官方资料:新特征和Bugfix列表,所有工具开发说明
    日本太笨了,以小目标发动大战争,而且偷袭时候如小贼入室,一旦得手就仓皇逃窜
    理论经典:TCP协议的3次握手与4次挥手过程详解
    C++没有库则寸步难行,有库则几乎可以做任何事情——Bjarne Stroustrupi
    Ruby已经慢慢走向衰退了,那些年代久远而且小众的语言没有翻身的可能性
    前端面试题精选
    Spring MVC 基础
    NET WEB
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/2987547.html
Copyright © 2011-2022 走看看