[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.

时间: 2024-11-08 17:25:16

[NOI导刊2011]影像之结构化特征的相关文章

贪心—— P1809 过河问题_NOI导刊2011提高(01)

洛谷——P1809 过河问题_NOI导刊2011提高(01) 题目描述 有一个大晴天,Oliver与同学们一共N人出游,他们走到一条河的东岸边,想要过河到西岸.而东岸边有一条小船. 船太小了,一次只能乘坐两人.每个人都有一个渡河时间T,船划到对岸的时间等于船上渡河时间较长的人所用时间. 现在已知N个人的渡河时间T,Oliver想要你告诉他,他们最少要花费多少时间,才能使所有人都过河. 注意,只有船在东岸(西岸)的人才能坐上船划到对岸. 输入输出格式 输入格式: 输入文件第一行为人数N,以下有N行

NOI导刊模拟题(1)

最大音量 动态规划 题意:给出一个初始值和一个变化序列 c,在第 i 步可以加上或减去 c[i],求 n 步之后能达到的最大值.有一个限定值 maxlevel,在变化过程中值不能超过 maxlevel 也不能低于 0. 初步解法:搜索.每一步两种决策,及时阻止无效状态的搜索. 然后是(来自 lzw 大神的)剪枝: 如果当前已经找到的答案达到了 Maxlevel 就直接退出: 如果当前值加上后面所有的值也无法超过当前找到的答案就退出: 对于重复状态只搜索一次. 从第三步看出来其实是个动规. 正解:

洛谷 P1808 单词分类_NOI导刊2011提高(01)

P1808 单词分类_NOI导刊2011提高(01) 题目描述 Oliver为了学好英语决定苦背单词,但很快他发现要直接记住杂乱无章的单词非常困难,他决定对单词进行分类. 两个单词可以分为一类当且仅当组成这两个单词的各个字母的数量均相等. 例如“AABAC”,它和“CBAAA”就可以归为一类,而和“AAABB”就不是一类. 现在Oliver有N个单词,所有单词均由大写字母组成,每个单词的长度不超过100.你要告诉Oliver这些单词会被分成几类. 输入输出格式 输入格式: 输入文件的第一行为单词

单人纸牌_NOI导刊2011提高(04)

题目描述 单人纸牌游戏,共36张牌分成9叠,每叠4张牌面向上.每次,游戏者可以从某两个不同的牌堆最顶上取出两张牌面相同的牌(如黑桃10和梅花10)并且一起拿走.如果最后所有纸牌都被取走,则游戏者就赢了,否则游戏者就输了. George很热衷于玩这个游戏,但是一旦有时有多种选择的方法,George就不知道取哪一种好了,George会从中随机地选择一种走,例如:顶上的9张牌为KS,KH,KD,9H,8S,8D,7C,7D,6H,显然有5种取法:(KS,KH),(KS,KD),(KH,KD),(8S,

[luoguP1835] 素数密度_NOI导刊2011提高(04)(素数筛)

传送门 数据辣么大,怎么搞?(L≤R≤2147483647) 注意到R-L≤1000000 所以可以直接筛R-L区间内的数, 但是需要用已知的小的素数筛, R-L区间内的大部分数肯定能用较小的素数筛去,但是还有一些较大的数,可能等于两个大质数的乘积,没法被筛去. 但是又注意到,数据最大才10位,也就是说我们只需要用位数<=5的素数筛就可以了,所以先预处理出来,直接筛就ok了. #include <cstdio> #define N 1000001 #define max(x, y) ((

洛谷 P1835 素数密度_NOI导刊2011提高(04)题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=1835 题目描述 给定区间[L,R](L≤R≤2147483647,R-L≤1000000),请计算区间中素数的个数. 输入输出格式 输入格式: 两个数L和R. 输出格式: 一行,区间中素数的个数. 输入输出样例 输入样例#1: 2 11 输出样例#1: 5 分析:裸的区间素数筛.代码中有详细注释(其中区间素数筛函数大部分借用了<挑战程序

Luogu P1836 数页码_NOI导刊2011提高(04)

题目描述 一本书的页码是从1-n编号的连续整数:1,2,3,-,n.请你求出全部页码中所有单个数字的和,例如第123页,它的和就是1+2+3=6. 输入输出格式 输入格式: 一行为n(1≤n≤1O^9). 输出格式: 一行,代表所有单个数字的和. 输入输出样例 输入样例#1: 3456789 输出样例#1: 96342015  Solution 本题是让我们求1~n这n个数所有单个数字的和,我们可以试着把每一位所有出现过的数字的和先求出来,然后把每一位的答案加起来就是最终的答案了. 我们就看"3

luogu P1809 过河问题_NOI导刊2011提高(01)

题目描述 有一个大晴天,Oliver与同学们一共N人出游,他们走到一条河的东岸边,想要过河到西岸.而东岸边有一条小船. 船太小了,一次只能乘坐两人.每个人都有一个渡河时间T,船划到对岸的时间等于船上渡河时间较长的人所用时间. 现在已知N个人的渡河时间T,Oliver想要你告诉他,他们最少要花费多少时间,才能使所有人都过河. 注意,只有船在东岸(西岸)的人才能坐上船划到对岸. 输入输出格式 输入格式: 输入文件第一行为人数N,以下有N行,每行一个数. 第i+1行的数为第i个人的渡河时间. 输出格式

NOI导刊2010提高(06) 黑匣子

题目描述 Black Box是一种原始的数据库.它可以储存一个整数数组,还有一个特别的变量i.最开始的时候Black Box是空的.而i等于0.这个Black Box要处理一串命令. 命令只有两种: ADD(x):把x元素放进BlackBox; GET:i加1,然后输出Blackhox中第i小的数. 记住:第i小的数,就是Black Box里的数的按从小到大的顺序排序后的第i个元素.例如: 我们来演示一下一个有11个命令的命令串.(如下图所示) 现在要求找出对于给定的命令串的最好的处理方法.AD