• CF(435D


    题目链接:http://codeforces.com/problemset/problem/435/D  

    题意:求三角形个数,三个点必须的白点上,而且三条边必须是横线,竖线或对角线,三条边上不同意出现黑点。

    解法:dp,计算以每一个点为三角形左下角的个数,当中共同拥有8种形状。为了O(1)查询某段横线竖线和对角线是否有黑点,须要预处理各个方向的黑点数量;


    代码:

    /******************************************************
    * @author:xiefubao
    *******************************************************/
    #pragma comment(linker, "/STACK:102400000,102400000")
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <queue>
    #include <vector>
    #include <algorithm>
    #include <cmath>
    #include <map>
    #include <set>
    #include <stack>
    #include <string.h>
    //freopen ("in.txt" , "r" , stdin);
    using namespace std;
    
    #define eps 1e-8
    #define zero(_) (abs(_)<=eps)
    const double pi=acos(-1.0);
    typedef long long LL;
    const int Max=100010;
    const int INF=1e9+7;
    
    LL ans=0;
    char s[410][410];
    int heng[410][410];
    int shu[410][410];
    int xie1[410][410];
    int xie2[410][410];
    int n,m;
    bool OK1(int i,int j,int k)
    {
        return xie2[i][j]-xie2[i-k][j+k]==0;
    }
    bool OK2(int i,int j,int k)
    {
        return heng[i][j+k]-heng[i][j]==0;
    }
    bool OK3(int i,int j,int k)
    {
        return xie1[i][j]-xie1[i-k][j-k]==0;
    }
    bool OK4(int i,int j,int k)
    {
        return shu[i][j]-shu[i-k][j]==0;
    }
    bool OK(int i,int j)
    {
        return i>=0&&i<n&&j>=0&&j<m;
    }
    int main()
    {
        cin>>n>>m;
        for(int i=0; i<n; i++)
            scanf("%s",s[i]);
        for(int i=0; i<n; i++)
        {
            heng[i][0]=(s[i][0]=='1');
            for(int j=1; j<m; j++)
                heng[i][j]=heng[i][j-1]+(s[i][j]=='1');
        }
        for(int i=0; i<m; i++)
        {
            shu[0][i]=(s[0][i]=='1');
            for(int j=1; j<n; j++)
                shu[j][i]=shu[j-1][i]+(s[j][i]=='1');
        }
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<m; j++)
            {
                xie1[i][j]=(s[i][j]=='1');
                if(OK(i-1,j-1))
                    xie1[i][j]+=xie1[i-1][j-1];
            }
        }
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<m; j++)
            {
                xie2[i][j]=(s[i][j]=='1');
                if(OK(i-1,j+1))
                    xie2[i][j]+=xie2[i-1][j+1];
            }
        }
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
            {
                if(s[i][j]=='1') continue;
                for(int k=1; k<=min(i,j); k++)
                {
                    if(s[i][j-k]=='0'&&s[i-k][j]=='0'&&OK1(i,j-k,k))
                        ans++;
                    if(s[i][j-k]=='1'||s[i-k][j]=='1')
                        break;
                }
            }
        //cout<<ans<<endl;
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
            {
                if(s[i][j]=='1') continue;
                for(int k=1; k<=min(i,j); k++)
                {
                    if(s[i][j-k]=='0'&&s[i-k][j-k]=='0'&&OK4(i,j-k,k))
                        ans++;
                    if(s[i][j-k]=='1'||s[i-k][j-k]=='1')
                        break;
                }
            }
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
            {
                if(s[i][j]=='1') continue;
                for(int k=1; k<=min(i,j); k++)
                {
                    if(s[i-k][j]=='0'&&s[i-k][j-k]=='0'&&OK2(i-k,j-k,k))
                        ans++;
                    if(s[i-k][j]=='1'||s[i-k][j-k]=='1')
                        break;
                }
            }
        //cout<<ans<<endl;
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
            {
                if(s[i][j]=='1') continue;
                for(int k=1; k<=min(i,m-j-1); k++)
                {
                    if(s[i-k][j]=='0'&&s[i-k][j+k]=='0'&&OK2(i-k,j,k))
                        ans++;
                    if(s[i-k][j]=='1'||s[i-k][j+k]=='1')
                        break;
                }
            }
        //cout<<ans<<endl;
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
            {
                if(s[i][j]=='1') continue;
                for(int k=1; k<=min(j,min(i,m-j-1)); k++)
                {
                    if(s[i-k][j-k]=='0'&&s[i-k][j+k]=='0'&&OK2(i-k,j-k,2*k))
                        ans++;
                    if(s[i-k][j-k]=='1'||s[i-k][j+k]=='1')
                        break;
                }
            }
        //cout<<ans<<endl;
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
            {
                if(s[i][j]=='1') continue;
                for(int k=1; k<=j&&2*k<=i; k++)
                {
                    if(s[i-k][j-k]=='0'&&s[i-2*k][j]=='0'&&s[i-2*k+1][j]=='0'&&OK1(i-k,j-k,k))
                        ans++;
                    if(s[i-k][j-k]=='1'||s[i-2*k][j]=='1'||s[i-2*k+1][j]=='1')
                        break;
                }
            }
        //cout<<ans<<endl;
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
            {
                if(s[i][j]=='1') continue;
                for(int k=1; k<=m-1-j&&2*k<=i; k++)
                {
                    if(s[i-k][j+k]=='0'&&s[i-2*k][j]=='0'&&s[i-2*k+1][j]=='0'&&OK3(i-k,j+k,k))
                        ans++;
                    if(s[i-k][j+k]=='1'||s[i-2*k][j]=='1'||s[i-2*k+1][j]=='1')
                        break;
                }
            }
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
            {
                if(s[i][j]=='1') continue;
                for(int k=1; k<=j&&2*k<=j; k++)
                {
                    if(s[i][j-2*k]=='0'&&s[i][j-2*k+1]=='0'&&s[i-k][j-k]=='0'&&OK1(i,j-2*k,k))
                        ans++;
                    if(s[i][j-2*k]=='1'||s[i][j-2*k+1]=='1'||s[i-k][j-k]=='1')
                        break;
                }
            }
        cout<<ans<<endl;
        return 0;
    }
    

  • 相关阅读:
    trie树
    单调队列
    网络流24题——试题库问题
    费用流的简单应用
    Manacher算法
    KMP算法
    网络流之最小费用最大流
    网络流之二分图匹配【转】
    网络流之最大流
    矩阵快速幂优化菲波那切数列
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5165165.html
Copyright © 2020-2023  润新知