http://acm.timus.ru/problem.aspx?space=1&num=1221
算是枚举的 题目意思是必须划出这样的 11011
10001
00000
10001
11011
注意中间必须是完整的0,不多不少,旁边的1也是如此 不多不少 才可以
题目很简单 预处理出1的个数 以及以当前0为最低顶角的最大正方形的边长 判断一下1的个数是否满足就可
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 using namespace std; 9 int a[110][110],dp[110][110],sum[110][110]; 10 int main() 11 { 12 int i,j,n,maxz,g; 13 while(cin>>n) 14 { 15 if(!n) break; 16 memset(sum,0,sizeof(sum)); 17 memset(dp,0,sizeof(dp)); 18 maxz=0; 19 for(i = 1; i <= n ; i++) 20 for(j = 1; j <= n ; j++) 21 { 22 cin>>a[i][j]; 23 if(a[i][j]==0) dp[i][j] = 1; 24 sum[i][j] = sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]; 25 if(a[i][j]==1) sum[i][j]++; 26 } 27 for(i = 2; i <= n ; i++) 28 for(j = 2 ; j <= n ;j++) 29 if(a[i][j]==0) 30 { 31 int k = (min(dp[i-1][j],dp[i-1][j-1]),dp[i-1][j+1]); 32 if(i>=2*k+1&&a[i-2*k][j]==0) 33 dp[i][j] = k+1; 34 else 35 dp[i][j] = 1; 36 //cout<<dp[i][j]<<" "<<i<<" "<<j<<endl; 37 } 38 int b[110] = {0}; 39 b[1] = 1; 40 for(i = 2; i <= 100 ; i++) 41 b[i] = b[i-1]+4*(i-1); 42 for(i =1; i <= n ; i++) 43 for(j = 1; j <= n ;j++) 44 { 45 if(a[i][j]==1) 46 { 47 int x=0; 48 for(g = j ; g >= 1 ; g--) 49 if(a[i][g]==0) 50 break; 51 else x++; 52 if(i<2*x+1||j<2*x+1) continue; 53 int s = sum[i][j]-sum[i-2*x-1][j]-sum[i][j-2*x-1]+sum[i-2*x-1][j-2*x-1]; 54 //if(i==5&&j==5) 55 //cout<<dp[i][j-x]<<" "<<x<<" "<<sum[i][j]<<endl; 56 if(dp[i][j-x]==x+1&&s==(2*x+1)*(2*x+1)-b[x+1]) 57 maxz = max(maxz,2*x+1); 58 } 59 } 60 if(maxz) 61 cout<<maxz<<endl; 62 else 63 puts("No solution"); 64 } 65 66 return 0; 67 }