zoukankan      html  css  js  c++  java
  • 1014

    A.三角形
    问题描述
    给你一个尺寸为(n imes m)的字符矩阵,请你找出矩阵中所有的“字同三角形”。

    所谓“字同三角形”是指由至少三个相同字符构成的“等腰直角三角形”,且直角边与矩阵的边平行。例如:下图矩阵中,含有7个“字同三角形”。

    最开始想的有点小偏 以为是(dfs)求联通块
    然后发现一些性质好像可以用动态规划来解决
    然后我就定义了一个三维的数组
    定义 (f[i][j][k])表示 在 以((i,j)) 为结尾的是否能够构成直角边长长度为k
    假如我们分四种情况来讨论直角三角形的情况
    我们有状态转移方程 这里只列举一种

    (ans+=(f[i][j][s+1]==f[i-1][j-1][s]);)

    然后就可以利用滚动数组优化掉空间
    然后我TLE 44...

    回去和某位巨佬谈论了一下 发现我的做法可以再优化一下 原因是多了一个k 动态规划怎么能没有决策呢??
    (f[i][j])表示((i,j)) 能够贡献的最大的高度
    称为三角形的充要条件是(i,j)的上一层最多能成为的高度和能够对 ((i,j))点对贡献它的高度个三角形 条件是((i,j))前面已经有了这么多能够达成的边长
    然后我们就可以 得到状态转移方程
    当然还可以枚举直角边

    	f[i][j]=min(ff[j]-1,f[i-1][j-1])+1;
    	ans+=f[i][j]-1;
    

    code:

    //
    #include<bits/stdc++.h>
    using namespace std;
    #define maxnn 2005
    int n,m;
    char ch[maxnn][maxnn];
    int f[maxnn][maxnn];
    int f2[maxnn][maxnn];
    int ff[maxnn];
    int k=1;
    int ans=0;
    void FIE() {
    	freopen("triangie.in","r",stdin);
    	freopen("triangie.out","w",stdout);
    }
    int main() {
    	//FIE();
    	cin>>n>>m;
    	for(int i=1; i<=n; i++) {
    		scanf("%s",ch[i]+1);
    	}
    	//case 1
    	for(int i=1; i<=n; i++) {
    		for(int j=0; j<=m; j++) {
    				f[i][j]=0;
    		}
    	}
    	for(int i=1; i<=n; i++) {
    		for(int j=1; j<=m; j++) {
    			ff[j]=1;
    			f[i][j]=1;
    		}
    		for(int j=1; j<=m; j++) {
    			if(ch[i][j-1]==ch[i][j]) {
    				ff[j]=ff[j-1]+1;
    			}
    			if(ch[i-1][j-1]==ch[i][j]) {
    			 {
    					{
    						f[i][j]=min(ff[j]-1,f[i-1][j-1])+1;
    						ans+=f[i][j]-1;
    					}
    				}
    			}
    		}
    	}
    	//case2
    
    	for(int i=1; i<=n; i++) {
    		for(int j=1; j<=m; j++) {
    				f[i][j]=0;
    		}
    	}
    	for(int i=1; i<=n; i++) {
    		for(int j=1; j<=m; j++) {
    			ff[j]=1;
    			f[i][j]=1;
    		}
    		for(int j=m; j>=1; j--) {
    			if(ch[i][j+1]==ch[i][j]) {
    				ff[j]=ff[j+1]+1;
    			}
    			if(ch[i-1][j+1]==ch[i][j]) {
    			 {
    					f[i][j]=min(ff[j]-1,f[i-1][j+1])+1;
    					ans+=f[i][j]-1;
    				}
    			}
    		}
    	}
    	//case 3
    
    	for(int i=1; i<=n; i++) {
    		for(int j=1; j<=m; j++) {
    				f[i][j]=0;
    				f[i][j]=1;
    		}
    	}
    	for(int i=n; i>=1; i--) {
    		for(int j=1; j<=m; j++) {
    			ff[j]=1;
    		}
    
    		for(int j=m; j>=1; j--) {
    			if(ch[i][j+1]==ch[i][j]) {
    				ff[j]=ff[j+1]+1;
    			}
    			if(ch[i+1][j+1]==ch[i][j]) {
    			 {
    					f[i][j]=min(ff[j]-1,f[i+1][j+1])+1;
    						ans+=f[i][j]-1;
    				}
    			}
    		}
    	}
    	//case 4
    	for(int i=1; i<=n; i++) {
    		for(int j=1; j<=m; j++) {
    				f[i][j]=0;
    				f[i][j]=1;
    		}
    	}
    	for(int i=n; i>=1; i--) {
    		for(int j=1; j<=m; j++) {
    			ff[j]=1;
    		}
    		for(int j=1; j<=m; j++) {
    			if(ch[i][j-1]==ch[i][j]) {
    				ff[j]=ff[j-1]+1;
    			}
    			if(ch[i+1][j-1]==ch[i][j]) {
    			 {
    			 {
    					f[i][j]=min(ff[j]-1,f[i+1][j-1])+1;
    						ans+=f[i][j]-1;
    				}
    			}
    
    			}
    		}
    	}
    	cout<<ans;
    }
    
  • 相关阅读:
    python--Tuple类型
    python--List类型
    剑指offer--数组中重复的数字
    Assignment HDU
    kuangbin 并查集
    Girls and Boys-hdu 1068
    Computer HDU
    Terrorist’s destroy HDU
    Roads in the North POJ
    Labyrinth POJ
  • 原文地址:https://www.cnblogs.com/OIEREDSION/p/11677257.html
Copyright © 2011-2022 走看看