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


  • 相关阅读:
    GridView动态删除Item
    GridView动态添加View
    Unity debug mode下的watermark去除
    Espresso unit test的输入法问题
    [troubleShooting]如何安装Andorid M preview到NEXUS系列机器
    [trouble-shooting]android 无法启动X86模式虚拟机的问题解决。
    Android studio+ndk 下面的gradle配置记录
    html call android apk的方法汇总
    Android studio 运行和编译的优化
    Android Installation error: INSTALL_FAILED_UID_CHANGED的解决办法
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/2987547.html
Copyright © 2011-2022 走看看