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;
    }
    
  • 相关阅读:
    Azure PowerShell (2) 修改Azure订阅名称
    Windows Azure Platform Introduction (11) 了解Org ID、Windows Azure订阅、账户
    Azure PowerShell (3) 上传证书
    Azure PowerShell (1) PowerShell入门
    Windows Azure Service Bus (2) 队列(Queue)入门
    Windows Azure Service Bus (1) 基础
    Windows Azure Cloud Service (10) Role的生命周期
    Windows Azure Cloud Service (36) 在Azure Cloud Service配置SSL证书
    Android studio 使用心得(一)—android studio快速掌握快捷键
    android 签名、混淆打包
  • 原文地址:https://www.cnblogs.com/OIEREDSION/p/11677257.html
Copyright © 2011-2022 走看看