UVa 201 Squares
题意:
给出这样一个图,求一共有多少个大小不同或位置不同的正方形。
分析:
这种题一看就有思路,最开始的想法就是枚举正方形的位置,需要二重循环,枚举边长一重循环,判断是否为正方形又需要一重循环,复杂度为O(n4),对于n≤9来说,这个复杂度可以接受。
可以像预处理前缀和那样,用O(1)的时间判断是否为正方形,这样总的复杂度就优化到O(n3)。
这个方法转自这里
We can think that vertical or horizontal lines are edges between two adjecent point. After that we can take a three dimensional array (say a [N][N][2]) to store the count of horizontal(a[i][j][0]) edges and vertical(a[i][j][1]) edges. a[i][j][0] contains number of horizontal edges at row i upto coloumn j. and a[i][j][1] contains number of vertical edges at coloumn j upto row i. Next you use a O(n^2) loop to find a square. a square of size 1 is found if there is an edge from (i,j) to (i,j+1) and (i,j+1) to (i+1,j+1) and (i,j) to (i+1,j) and (i+1,j) to (i+1,j+1) we can get this just by subtracting values calculated above.
举个例子,a[i][j][0]表示在第i行上,从第一列到第j列水平边数,如果a[i][j+l][0] - a[i][j][0],说明点(i, j)到(i, j+l)有一条长为l的水平线段。
我还被输入坑了,注意VH后面,哪个数代表行,哪个数代表列。
1 #include <cstdio> 2 #include <cstring> 3 4 const int maxn = 10; 5 bool G[2][maxn][maxn]; 6 int a[2][maxn][maxn], cnt[maxn]; 7 8 int main() 9 { 10 //freopen("in.txt", "r", stdin); 11 int n, m, kase = 0; 12 while(scanf("%d", &n) == 1 && n) 13 { 14 memset(G, false, sizeof(G)); 15 memset(a, 0, sizeof(a)); 16 memset(cnt, 0, sizeof(cnt)); 17 scanf("%d", &m); 18 getchar(); 19 for(int k = 0; k < m; ++k) 20 { 21 char c; 22 int i, j; 23 scanf("%c %d %d", &c, &i, &j); 24 getchar(); 25 if(c == 'H') G[0][i][j+1] = true; 26 else G[1][j+1][i] = true; 27 } 28 for(int i = 1; i <= n; ++i) 29 for(int j = 1; j <= n; ++j) 30 { 31 a[0][i][j] = a[0][i][j-1] + G[0][i][j]; 32 a[1][i][j] = a[1][i-1][j] + G[1][i][j]; 33 } 34 35 for(int i = 1; i < n; ++i) 36 for(int j = 1; j < n; ++j) //枚举正方形的左上角 37 for(int l = 1; i+l<=n && j+l<=n; ++l) //枚举正方形的边长 38 if(a[0][i][j+l]-a[0][i][j] == l && a[0][i+l][j+l]-a[0][i+l][j] == l 39 && a[1][i+l][j]-a[1][i][j] == l && a[1][i+l][j+l]-a[1][i][j+l] == l) 40 cnt[l]++; 41 42 if(kase) printf("\n**********************************\n\n"); 43 printf("Problem #%d\n\n", ++kase); 44 bool flag = false; 45 for(int i = 1; i <= n; ++i) if(cnt[i]) 46 { 47 printf("%d square (s) of size %d\n", cnt[i], i); 48 flag = true; 49 } 50 if(!flag) puts("No completed squares can be found."); 51 } 52 53 return 0; 54 }