URAL_1008. Image Encoding

题目大意:一个图像可以用数种方法表示。现在我们将要考虑一个图像的两种表示。我们假设一个图像是由黑白像素组成的。

图像中至少有一个黑像素并且所有的黑像素都互相连接。黑像素的坐标下界不会超过1,上界不会超过10。下图是一个符合要求的图像。

12e825a7-e4fd-4257-90c4-be3e50526011.png

两种表示都唯一地描述了黑像素的排列方案。第一种表示的第一行是黑像素的个数。接下来的几行是每一个黑像素的坐标。它们是按X轴的递增序给出的。如果X轴相等,则相等的那些像素按Y轴的递增序给出。于是上图可表示为:

6
2 3
2 4
3 3
3 4
4 2
4 3

第二种表示法的第一行是最左下角的黑像素的坐标。接下来的每行描述了每个像素的相邻像素。首先给出的是最左下角的黑像素的相邻像素描述,接下来是它第一个相邻像素的相邻像素描述(如果第一个相邻像素存在的话),然后是它第二个相邻像素的描述(如果第二个相邻像素存在的话),以此类推。

每行描述有以下字母描述各个像素的相邻像素:R表示在右边,T表示在上边,L表示在左边,B表示在下边。各个像素的描述是从右边相邻像素起以逆时针顺序给出的。每行描述以","作为结尾。最后一行以"."作为结尾。于是上图可以表示为:

2 3
RT,
RT,
,
B,
,
.
每行前后没有多余的空格
输入:一种图像的表示方法
输出:另外一种图像的表示方法
View Code
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
using namespace std;

int n,minx,miny;
int map[12][12];
int visit[12][12];
int dir[4][2]={1,0,0,1,-1,0,0,-1};
//dir2[][]    是根据字符转化坐标,对R,T,L,B四个字符分别对7取余
//得到四个不同的数,然后取下标判断方向
int dir2[7][2]={0,1,0,0,0,0,0,-1,0,0,1,0,-1,0};
char s[]="RTLB";

struct point
{    int x,y;    };

int check(int x,int y)
{
    return x>0&&x<=10&&y>0&&y<=10;
}
void BFS1()
{
    int x,y,x1,y1,i,count=0;
    queue<point> q;
    point tmp;
    tmp.x=minx,tmp.y=miny;
    q.push(tmp);
    visit[minx][miny]=1;
    while(!q.empty())
    {
        tmp=q.front();    q.pop();
        x1=tmp.x;    y1=tmp.y;
        for(i=0;i<4;i++)
        {
            x=x1+dir[i][0];    y=y1+dir[i][1];
            if(check(x,y)&&map[x][y]&&!visit[x][y])
            {
                putchar(s[i]);
                tmp.x=x;        tmp.y=y;
                q.push(tmp);    visit[x][y]=1;
            }
        }
        count++;
        if(count==n)    puts(".");
        else puts(",");
    }
}

void BFS2()
{
    int x,y,tx,ty,len,i,j,count;
    char str[12];
    scanf("%d",&miny);    minx=n;
    queue<point> q;
    point tmp;
    tmp.x=minx;    tmp.y=miny;
    q.push(tmp);
    visit[minx][miny]=1;
    while(!q.empty())
    {
        tmp=q.front();    q.pop();
        x=tmp.x;    y=tmp.y;
        scanf("%s",str);
        len=strlen(str);
        for(i=0;i<len-1;i++)
        {
            tx=dir2[str[i]%7][0];    ty=dir2[str[i]%7][1];
            visit[x+tx][y+ty]=1;
            tmp.x=x+tx;    tmp.y=y+ty;
            q.push(tmp);
        }
        if(str[0]=='.')    break;
    }    
    for(count=0,i=1;i<=10;i++)
    {
        for(j=1;j<=10;j++)
            if(visit[i][j])    count++;
    }
    printf("%d\n",count);
    for(i=1;i<=10;i++)
    {
        for(j=1;j<=10;j++)
            if(visit[i][j])    printf("%d %d\n",i,j);
    }
}

int main()
{
    int x,y,i;
    char ch;
    while(scanf("%d",&n)!=EOF)
    {
        memset(map,0,sizeof(map));
        memset(visit,0,sizeof(visit));
        if(ch=getchar()=='\n')
        {
            minx=miny=10;
            for(i=0;i<n;i++)
            {
                scanf("%d%d",&x,&y);
                if(x<minx)    minx=x,miny=y;
                else if(x==minx&&y<miny)    miny=y;
                map[x][y]=1;
            }
            printf("%d %d\n",minx,miny);
            BFS1();
        }
        else BFS2();
    }
    return 0;
}

转载于:https://www.cnblogs.com/pcoda/archive/2012/05/05/2484891.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值