POJ 1111 Image Perimeters

来源:互联网 发布:京东和淘宝年销售额 编辑:程序博客网 时间:2024/06/13 13:40
Image Perimeters
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 8178 Accepted: 4903
Description

Technicians in a pathology lab analyze digitized images of slides. Objects on a slide are selected for analysis by a mouse click on the object. The perimeter of the boundary of an object is one useful measure. Your task is to determine this perimeter for selected objects.

The digitized slides will be represented by a rectangular grid of periods, '.', indicating empty space, and the capital letter 'X', indicating part of an object. Simple examples are

XX Grid 1 .XXX Grid 2

XX .XXX

.XXX

...X

..X.

X...

An X in a grid square indicates that the entire grid square, including its boundaries, lies in some object. The X in the center of the grid below is adjacent to the X in any of the 8 positions around it. The grid squares for any two adjacent X's overlap on an edge or corner, so they are connected.

XXX

XXX Central X and adjacent X's

XXX

An object consists of the grid squares of all X's that can be linked to one another through a sequence of adjacent X's. In Grid 1, the whole grid is filled by one object. In Grid 2 there are two objects. One object contains only the lower left grid square. The remaining X's belong to the other object.

The technician will always click on an X, selecting the object containing that X. The coordinates of the click are recorded. Rows and columns are numbered starting from 1 in the upper left hand corner. The technician could select the object in Grid 1 by clicking on row 2 and column 2. The larger object in Grid 2 could be selected by clicking on row 2, column 3. The click could not be on row 4, column 3.


One useful statistic is the perimeter of the object. Assume each X corresponds to a square one unit on each side. Hence the object in Grid 1 has perimeter 8 (2 on each of four sides). The perimeter for the larger object in Grid 2 is illustrated in the figure at the left. The length is 18.

Objects will not contain any totally enclosed holes, so the leftmost grid patterns shown below could NOT appear. The variations on the right could appear:

Impossible Possible



XXXX XXXX XXXX XXXX

X..X XXXX X... X...

XX.X XXXX XX.X XX.X

XXXX XXXX XXXX XX.X



..... ..... ..... .....

..X.. ..X.. ..X.. ..X..

.X.X. .XXX. .X... .....

..X.. ..X.. ..X.. ..X..

..... ..... ..... .....
Input

The input will contain one or more grids. Each grid is preceded by a line containing the number of rows and columns in the grid and the row and column of the mouse click. All numbers are in the range 1-20. The rows of the grid follow, starting on the next line, consisting of '.' and 'X' characters.

The end of the input is indicated by a line containing four zeros. The numbers on any one line are separated by blanks. The grid rows contain no blanks.
Output

For each grid in the input, the output contains a single line with the perimeter of the specified object.
Sample Input

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
Sample Output

8
18
40
48

8


因为不会用数组来朝每个方向走,被小伙伴嘲笑了。。。。

广搜的知识,用深搜也行的,代码量就会少的,才开始做这种题,很多不会的。

这道题一开始是读不懂题,不知道他要干嘛,数据也算不出来,然后愣了几分钟,恍然大悟,首先是联通块的知识点,给出一幅图,再给岀一个格子的位置,求这个格子所在的连通块的最外边框需要多少个点来连接。

好,现在开始联想。。。。。。实验室里的桌子上有一个培养皿,科学家们都去忙别的去了,只有我在这个培养皿旁边,自己想出了一个细菌所在的位置,然后找到这个细菌的所在的连通块,然后描出细菌的框框。输出一共有多少个点。

这样并不好写,格子里的细菌是一个数组,格子又是一个数组,他们的位置不在一起,所以要把他们转化在一起,将细菌缩小化,想成一个点,然后往左上角移,这样就和格子共用一个位置啦。(细菌的点和格子的点都在一块)

有一个细菌被找到,就把这个细菌格子上的四个点计数,把一个连通块的细菌都找到之后,每个点都有计数了,仔细想想就可以知道,一个点如果被计算了4次,这个点一定是在细菌中间的,不再边界上,如果为1,2,3的时候,就在边界上,而2又比较特殊,如果是两个细菌在一个对角线上的话,他们共有的这个点就要被记为两次,就是加两次到总和上。



#include <iostream>#include <cstdio>#include <cstring>#include <queue>//#include <map>#include <algorithm>using namespace std;struct point{    int x,y;}point;int a[1005][1005],b[1005][1005];char s[30][30];int map[50][50];int main(void){   // freopen("F.txt","r",stdin);    int n,m;    while(scanf("%d%d%d%d",&n,&m,&point.x,&point.y),(n||m||point.x||point.y))    {        memset(map,0,sizeof(map));        memset(a,0,sizeof(a));        memset(b,0,sizeof(b));        for(int i=1;i<=n;i++)        {            getchar();            for(int j=1;j<=m;j++)            {                scanf("%c",&s[i][j]);                if(s[i][j]=='.')                    b[i][j]=1;            }        }        queue<struct point>p;      //  map<struct point,int>q;        p.push(point);        b[point.x][point.y]=1;        struct point t1,t2,t3,t4;        t1.x=point.x;t1.y=point.y;        t2.x=point.x+1;t2.y=point.y;        t3.x=point.x;t3.y=point.y+1;        t4.x=point.x+1;t4.y=point.y+1;      //  q.insert(t1);q.insert(t2);q.insert(t3);q.insert(t4);        map[t1.x][t1.y]++;        map[t2.x][t2.y]++;        map[t3.x][t3.y]++;        map[t4.x][t4.y]++;        while(!p.empty())        {            struct point tmp;            tmp.x=p.front().x;tmp.y=p.front().y;            p.pop();            if(a[tmp.x-1][tmp.y]<1000&&b[tmp.x-1][tmp.y]==0&&tmp.x-1>0&&tmp.y<=m)            {                struct point t;                t.x=tmp.x-1;t.y=tmp.y;                p.push(t);               b[tmp.x-1][tmp.y]=1;               a[tmp.x-1][tmp.y]=a[tmp.x][tmp.y]+1;                struct point t1,t2,t3,t4;        t1.x=t.x;t1.y=t.y;        t2.x=t.x+1;t2.y=t.y;        t3.x=t.x;t3.y=t.y+1;        t4.x=t.x+1;t4.y=t.y+1;              map[t1.x][t1.y]++;        map[t2.x][t2.y]++;        map[t3.x][t3.y]++;        map[t4.x][t4.y]++;             //  q.insert(t1);q.insert(t2);q.insert(t3);q.insert(t4);            }            if(a[tmp.x-1][tmp.y+1]<1000&&b[tmp.x-1][tmp.y+1]==0&&tmp.x-1>0&&tmp.y+1<=m)            {                struct point t;                t.x=tmp.x-1;t.y=tmp.y+1;                p.push(t);               b[tmp.x-1][tmp.y+1]=1;               a[tmp.x-1][tmp.y+1]=a[tmp.x][tmp.y]+1;                struct point t1,t2,t3,t4;        t1.x=t.x;t1.y=t.y;        t2.x=t.x+1;t2.y=t.y;        t3.x=t.x;t3.y=t.y+1;        t4.x=t.x+1;t4.y=t.y+1;              // q.insert(t1);q.insert(t2);q.insert(t3);q.insert(t4);        map[t1.x][t1.y]++;        map[t2.x][t2.y]++;        map[t3.x][t3.y]++;        map[t4.x][t4.y]++;            }            if(a[tmp.x][tmp.y+1]<1000&&b[tmp.x][tmp.y+1]==0&&tmp.x>0&&tmp.y+1<=m)            {                struct point t;                t.x=tmp.x;t.y=tmp.y+1;                p.push(t);               b[tmp.x][tmp.y+1]=1;               a[tmp.x][tmp.y+1]=a[tmp.x][tmp.y]+1;                struct point t1,t2,t3,t4;        t1.x=t.x;t1.y=t.y;        t2.x=t.x+1;t2.y=t.y;        t3.x=t.x;t3.y=t.y+1;        t4.x=t.x+1;t4.y=t.y+1;               //q.insert(t1);q.insert(t2);q.insert(t3);q.insert(t4);                map[t1.x][t1.y]++;        map[t2.x][t2.y]++;        map[t3.x][t3.y]++;        map[t4.x][t4.y]++;            }            if(a[tmp.x+1][tmp.y+1]<1000&&b[tmp.x+1][tmp.y+1]==0&&tmp.x+1<=n&&tmp.y+1<=m)            {                struct point t;                t.x=tmp.x+1;t.y=tmp.y+1;                p.push(t);               b[tmp.x+1][tmp.y+1]=1;               a[tmp.x+1][tmp.y+1]=a[tmp.x][tmp.y]+1;                struct point t1,t2,t3,t4;        t1.x=t.x;t1.y=t.y;        t2.x=t.x+1;t2.y=t.y;        t3.x=t.x;t3.y=t.y+1;        t4.x=t.x+1;t4.y=t.y+1;              // q.insert(t1);q.insert(t2);q.insert(t3);q.insert(t4);               map[t1.x][t1.y]++;        map[t2.x][t2.y]++;        map[t3.x][t3.y]++;        map[t4.x][t4.y]++;            }            if(a[tmp.x+1][tmp.y]<1000&&b[tmp.x+1][tmp.y]==0&&tmp.x+1<=n&&tmp.y<=m)            {                struct point t;                t.x=tmp.x+1;t.y=tmp.y;                p.push(t);               b[tmp.x+1][tmp.y]=1;               a[tmp.x+1][tmp.y]=a[tmp.x][tmp.y]+1;                struct point t1,t2,t3,t4;        t1.x=t.x;t1.y=t.y;        t2.x=t.x+1;t2.y=t.y;        t3.x=t.x;t3.y=t.y+1;        t4.x=t.x+1;t4.y=t.y+1;              // q.insert(t1);q.insert(t2);q.insert(t3);q.insert(t4);               map[t1.x][t1.y]++;        map[t2.x][t2.y]++;        map[t3.x][t3.y]++;        map[t4.x][t4.y]++;            }            if(a[tmp.x+1][tmp.y-1]<1000&&b[tmp.x+1][tmp.y-1]==0&&tmp.x+1<=n&&tmp.y-1>0)            {                struct point t;                t.x=tmp.x+1;t.y=tmp.y-1;                p.push(t);               b[tmp.x+1][tmp.y-1]=1;               a[tmp.x+1][tmp.y-1]=a[tmp.x][tmp.y]+1;                struct point t1,t2,t3,t4;        t1.x=t.x;t1.y=t.y;        t2.x=t.x+1;t2.y=t.y;        t3.x=t.x;t3.y=t.y+1;        t4.x=t.x+1;t4.y=t.y+1;              // q.insert(t1);q.insert(t2);q.insert(t3);q.insert(t4);               map[t1.x][t1.y]++;        map[t2.x][t2.y]++;        map[t3.x][t3.y]++;        map[t4.x][t4.y]++;            }            if(a[tmp.x][tmp.y-1]<1000&&b[tmp.x][tmp.y-1]==0&&tmp.x>0&&tmp.y-1>0)            {                struct point t;                t.x=tmp.x;t.y=tmp.y-1;                p.push(t);               b[tmp.x][tmp.y-1]=1;               a[tmp.x][tmp.y-1]=a[tmp.x][tmp.y]+1;                struct point t1,t2,t3,t4;        t1.x=t.x;t1.y=t.y;        t2.x=t.x+1;t2.y=t.y;        t3.x=t.x;t3.y=t.y+1;        t4.x=t.x+1;t4.y=t.y+1;               //q.insert(t1);q.insert(t2);q.insert(t3);q.insert(t4);                map[t1.x][t1.y]++;        map[t2.x][t2.y]++;        map[t3.x][t3.y]++;        map[t4.x][t4.y]++;            }            if(a[tmp.x-1][tmp.y-1]<1000&&b[tmp.x-1][tmp.y-1]==0&&tmp.x-1>0&&tmp.y-1>0)            {                struct point t;                t.x=tmp.x-1;t.y=tmp.y-1;                p.push(t);               b[tmp.x-1][tmp.y-1]=1;               a[tmp.x-1][tmp.y-1]=a[tmp.x][tmp.y]+1;                struct point t1,t2,t3,t4;        t1.x=t.x;t1.y=t.y;        t2.x=t.x+1;t2.y=t.y;        t3.x=t.x;t3.y=t.y+1;        t4.x=t.x+1;t4.y=t.y+1;              // q.insert(t1);q.insert(t2);q.insert(t3);q.insert(t4);               map[t1.x][t1.y]++;        map[t2.x][t2.y]++;        map[t3.x][t3.y]++;        map[t4.x][t4.y]++;            }        }        int sum=0;        for(int i=1;i<=n+1;i++)        {            for(int j=1;j<=m+1;j++)            {              //  printf("i:%d j:%d,sum:%d\n",i,j,map[i][j]);               // struct point t;              //  t.x=i;t.y=j;                if(map[i][j]==1||map[i][j]==3)                    sum++;                    else if(map[i][j]==2)                    {                       // printf("i:%d j:%d,sun:%d\n",i,j,map[i][j]);                        if((i-1>0&&j-1>0)&&((s[i][j]=='.'&&s[i-1][j-1]=='.')||(s[i][j-1]=='.'&&s[i-1][j]=='.')))                           {                                sum++;                               // printf("重复计算:i: %dj: %d sum: %d\n",i,j,map[i][j]);                           }                        sum++;                    }            }        }        printf("%d\n",sum);    }    return 0;}

0 0