• 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("
    **********************************
    
    ");
    43         printf("Problem #%d
    
    ", ++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
    ", cnt[i], i);
    48             flag = true;
    49         }
    50         if(!flag) puts("No completed squares can be found.");
    51     }
    52 
    53     return 0;
    54 }
    代码君
  • 相关阅读:
    oracle 10g 免安装客户端在windows下配置
    sql2005 sa密码
    使用windows live writer 有感
    windows xp SNMP安装包提取
    汉化groove2007
    迁移SQL server 2005 Reporting Services到SQL server 2008 Reporting Services全程截图操作指南
    foxmail 6在使用中的问题
    AGPM客户端连接不上服务器解决一例
    SpringSource Tool Suite add CloudFoundry service
    Java 之 SWing
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4206130.html
Copyright © 2020-2023  润新知