zoukankan      html  css  js  c++  java
  • ZOJ 1047【Image Perimeters】

      描述

    病理学实验室的技术人员分析幻灯片的数字化图像。通过鼠标点击幻灯片上的对象来选择分析对象。物体边界的周长是一个有用的量度。您的任务是确定选定对象的周长。  

      数字化幻灯片将由矩形周期网格表示,'. ',表示空白,大写字母“X”,表示对象的一部分。简单的例子有

      

      网格正方形中的一个X表示整个网格正方形,包括它的边界,位于某个对象中。下面网格中心的X在它周围的8个位置中的任何一个都与X相邻。任意两个相邻的X的网格正方形在一个边或角上重叠,因此它们是相连的。

      XXX
      XXX 中央X和相邻X
      XXX

      一个对象由所有X的网格正方形组成,这些正方形可以通过一系列相邻的X相互链接。在网格1中,整个网格由一个对象填充。在网格2中有两个对象。一个对象只包含左下角的网格正方形。剩余的X属于另一个对象。

      技术人员将总是点击一个X,选择包含该X的对象。点击的坐标被记录下来。行和列从左上角的1开始编号。技术人员可以通过单击第2行和第2列来选择网格1中的对象。网格2中较大的对象可以通过单击第2行第3列来选择。点击不能在第4行第3列。

      

       一个有用的统计数据是物体的周长。假设每个X对应于一个正方形,每边一个单位。因此,网格1中的对象具有周界8(四边各有2个)。网格2中较大对象的周长如图所示。长度是18。

      对象将不包含任何完全封闭的孔,因此下面显示的最左边的网格模式不会出现。右边的变化可能会出现:

      

      输入将包含一个或多个网格。每个网格前面都有一行,该行包含网格中的行数和列数以及鼠标单击的行和列数。所有数字都在1-20之间。网格的行从下一行开始,由“.”组成和“X”字符。 输入的结尾由一条包含四个零的线表示。任何一行上的数字都用空格隔开。网格行不包含空格。

       对于输入中的每个网格,输出包含带有指定对象周长的单行。

    输入输出样例

    输入样例1

    2 2 2 2
    XX
    XX
    6 4 2 3
    .XXX
    .XXX
    .XXX
    ...X
    ..X.
    X...
    5 6 1 3
    .XXXX.
    X....X
    ..XX.X
    .X...X
    ..XXX.
    7 7 2 6
    XXXXXXX
    XX...XX
    X..X..X
    X..X...
    X..X..X
    X.....X
    XXXXXXX
    7 7 4 4
    XXXXXXX
    XX...XX
    X..X..X
    X..X...
    X..X..X
    X.....X
    XXXXXXX
    0 0 0 0

    输出样例1

    8
    18
    40
    48
    8
    

    解题思路

      这里我8个方向我分成两次搜索:首先搜索相邻的(上下左右),如果还有X,就加入队列,并改成Y,如果没有X或者Y,周长就加一,然后搜索斜方向的,这个就直接进入队列,最后输出ans即可。

    题解

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n,m,x,y,ans;
     4 struct node{
     5     int X;
     6     int Y;//坐标 
     7     node(){}
     8     node(int xx,int yy) 
     9     {
    10         X=xx;
    11         Y=yy;
    12     }
    13 };
    14 queue<node> q;
    15 char mp[101][101];
    16 const int dir1[4][2]={0,1,0,-1, 1,0,-1, 0};//相邻 
    17 const int dir2[4][2]={1,1,1,-1,-1,1,-1,-1};//对角 
    18 void dfs()
    19 {
    20     q.push(node(x,y));
    21     mp[x][y]='Y';//打标记 
    22     while(!q.empty())
    23     {
    24         node head=q.front();
    25         q.pop();
    26         for(int i=0;i<4;i++)//相邻 
    27         {
    28             int tx=head.X+dir1[i][0];
    29             int ty=head.Y+dir1[i][1];
    30             if(mp[tx][ty]!='X'&&mp[tx][ty]!='Y')//没有了 
    31             {
    32                 ans++;//周长加一 
    33             }
    34             else
    35             {
    36                 if(mp[tx][ty]=='X')//有的话 
    37                 {
    38                     mp[tx][ty]='Y';//标记 
    39                     q.push(node(tx,ty));//继续搜 
    40                 }
    41             }
    42         }
    43         for(int i=0;i<4;i++)//对角 
    44         {
    45             int tx=head.X+dir2[i][0];
    46             int ty=head.Y+dir2[i][1];
    47             if(mp[tx][ty]=='X')//有的话进去就完事儿了 
    48             {
    49                 mp[tx][ty]='Y';
    50                 q.push(node(tx,ty));
    51             }
    52         }
    53     }
    54     cout<<ans<<endl;///输出答案 
    55 }
    56 int main()
    57 {
    58     while(cin>>n>>m>>x>>y&&n)//while输入 
    59     {
    60         for(int i=1;i<=51;i++)
    61         {
    62             for(int j=1;j<=51;j++)
    63             {
    64                 mp[i][j]=' ';//一定记得要清零 
    65             }
    66         }
    67         ans=0;//清空周长 
    68         for(int i=1;i<=n;i++)
    69         {
    70             for(int j=1;j<=m;j++)
    71             {
    72                 cin>>mp[i][j];//存图 
    73             }
    74         }
    75         dfs();    
    76     } 
    77     return 0;
    78 }

      

  • 相关阅读:
    【读书笔记】iOS-简单的数据驱动程序
    数据结构—单链表(类C语言描写叙述)
    使用Hadoop ACL 控制訪问权限
    Iocomp控件之数字显示【图文】
    维护的JSP站点数据丢失
    Simditor用法
    Android实战简易教程-第二十六枪(基于ViewPager实现微信页面切换效果)
    Deferred Rendering(三)反锯齿和半透明问题
    iOS Code Sign error: Provisioning profile can&#39;t be found 解决方式
    spring
  • 原文地址:https://www.cnblogs.com/hualian/p/11186349.html
Copyright © 2011-2022 走看看