zoukankan      html  css  js  c++  java
  • [NOI导刊2011]影像之结构化特征

    问题描述

        在影像比对中,有一种方法是利用影像中的边缘(edge)资讯,计算每个边缘资讯中具有代表性的结构化特征,以作为比对两张影像是否相似的判断标准。Water-filling方法是从每个边缘图的一个端点开始,绕着相连的边缘点走并依序编号。若走到某一步时,遇到一个以上不同的连接点,则分成不同路径同时继续走,直到没有任何连接点为止。如果一个点和另一个点为上下左右相邻,就称为连接。

    例如,在图1的影像中包含三个边缘图,每个边缘图由一些互相连接的边缘点构成。图中以黑色的方块代表边缘点,白色的方块代表背景。在Water-filling方法中,首先,从第一列(row)开始,由左至右,由上至下,先找到第一个黑点并编号为1。接着,找1的下一个尚未编号的连接点并编号为2。依此方法继续往下一个点前进依次编号。在编号6的点之后有两个尚未编号的连接点,此时,则分为两条路线,并同时编号为7继续往下走。当走到没有任何的相连点时,则结束现有边缘图的编号,并继续对影像中的其它边缘图编号。走完图1所有边缘图后所得到的编号如图2所示。所以,走完这三个边缘图所需要的步数分别为12、7及3;所以,12、7及3可以作为代表此张影像的结构化特征。请注意:位于斜对角上的两点不能算做连接,如:

     

        请写一个程序计算每个影像中,以Water-filling方法走完其中所有的边缘图后,将每个边缘图需走的步数依走访的顺序列出。

    输入说明

        输入文件包含一个正方形的影像。每组影像以图的宽度n开头(l≤n≤1000)。接下来的n行代表影像的内容:0表示背景的白点,1表示黑色的边缘点。

    输出说明

        对每一个输入的影像,以Water-filling方法走完所有的边缘图后,先印出此张影像中共有几个边缘图。接着,将每个边缘图需走的步数按升序列出。

    样例输入

    10

    0000000000

    0011110000

    0000010000

    0011111000

    0010110100

    0010010110

    0011110010

    0100010010

    0100000110

    0100000000

    样例输出

    3

    3

    7

    12

    思路

      是一个用来练宽搜的典型好题。你可以通过它搞懂宽搜的原理,搞懂深搜于宽搜的区别。

      记录每次宽搜有多少次入队,记录一共有多少次入队。

      输出入队次数的降序排列即可。

    type ss=record
        x,y,z:longint;
        end;
    
    const con:array[1..2,1..4] of longint=((1,-1,0,0),(0,0,-1,1));
    
    var a:array[0..1010,0..1010] of longint;
        f:array[0..1000000] of ss;
        b:array[0..1000000] of longint;
        n,i,sum,j:longint;
    
    procedure init;
    var ch:char;
    begin
        fillchar(a,sizeof(a),0);
        readln(n);
        for i:=1 to n do
            begin
                for j:=1 to n do
                    begin
                        read(ch);
                        if ch='1' then a[i,j]:=1;
                    end;
                readln;
            end;
    end;
    
    procedure sort(l,r:longint);
    var i,j,x,y:longint;
    begin
        i:=l;j:=r;x:=b[(l+r) div 2];
        repeat
            while b[i]<x do inc(i);
            while b[j]>x do dec(j);
            if i<=j then
                begin
                    y:=b[i];
                    b[i]:=b[j];
                    b[j]:=y;
                    inc(i);
                    dec(j);
                end;
        until i>j;
        if l<j then sort(l,j);
        if i<r then sort(i,r);
    end;
    
    procedure bfs(x,y:longint);
    var i,xx,yy,head,tail:longint;
    begin
        head:=0;tail:=1;
        f[1].x:=x;f[1].y:=y;f[1].z:=1;
        a[x,y]:=0;
        while head<tail do
            begin
                inc(head);
                for i:=1 to 4 do
                    begin
                        xx:=f[head].x+con[1,i];
                        yy:=f[head].y+con[2,i];
                        if a[xx,yy]=1 then
                            begin
                                inc(tail);
                                f[tail].x:=xx;
                                f[tail].y:=yy;
                                f[tail].z:=f[head].z+1;
                                a[xx,yy]:=0;
                            end;
                    end;
            end;
        inc(sum);
        b[sum]:=f[head].z;
    end;
    
    begin
        assign(input,'graph.in');
        assign(output,'graph.out');
        reset(input);
        rewrite(output);
        init;
        for i:=1 to n do
            for j:=1 to n do
                if a[j,i]=1 then
                    bfs(j,i);
        sort(1,sum);
        writeln(sum);
        for i:=1 to sum do
            writeln(b[i]);
        close(input);
        close(output); 
    end.
    View Code
  • 相关阅读:
    C++标准库vector以及迭代器
    (转)单链表的逆置
    (六)通过solr7的API实现商品的列表查询
    (八)solr7实现搜索框的自动提示并统计词频
    (四)DIH导入结构化数据
    (三)Solrj4到Solrj5的升级之路
    easyui validatebox 验证类型
    一、docker临时记录
    vip视频网站爬虫
    Intellij IDEA 4种配置热部署的方法
  • 原文地址:https://www.cnblogs.com/yangqingli/p/4930475.html
Copyright © 2011-2022 走看看