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;
    }
    


  • 相关阅读:
    Shell工具——cut、sed、awk、sort
    基于RocketMQ分布式事务实现
    Alpine Linux 包管理工具
    分布式事务之可靠消息最终一致性
    消息系统本质思考
    深入剖析Redis数据结构
    Feign原理深入剖析
    Shell中 /dev/null用法解析
    Lua 数据类型与变量
    分布式事务之Seata开源方案
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/2987547.html
Copyright © 2011-2022 走看看