zoukankan      html  css  js  c++  java
  • 矿藏估价

    某个矿藏丰富的地区埋有不同价值的矿藏。Mr. Chen某日记起他在此处有一块领地,于是他很想知道自己的领地上到底包含价值多少的矿物。他在该地区的地图上画出了领地的边界,请你来为他做一个资产评估。

    假定整个地区的地图为矩形。为了方便起见,我们把这个地区划分成若干单位正方形区域,每个区域以该处的矿藏价值标识。Mr. Chen划出的边界是一条封闭的曲线且不自交。边界经过的单位区域由于墨水的缘故,上面的矿藏价值标识变得不可辨认,保守估计,可认为价值为0。

    输入:第一行为两个整数N, M (1<= N<=50,1<=M<=50),表示地图有N行M列单位区域构成。接下来的N行为地图。每行有M个单位区域的标识,每个标识或者为一非负整数,表示该处矿藏价值;或者为‘*’,表示领地的边界经过这一单位区域。每两个单位区域的表示之间以至少一个空格隔开。

    输出:一个整数,即领地范围内所有矿藏的价值之和。

    输入样例
    5 6
    231 11 41 5 7 1
    13 * * * 31 34
    * 81 65 23 * 2
    1 * * * 7 1
    20 4 2 89 6 3
    输出样例
    169

    1、作图G=(V,E)。所有非边界的单位区域对应顶点集V中的一个顶点,V={vij | (i,j)非边界区域}。若两个非边界的单位区域相邻,则相应顶点之间有无向边。

     

    2、扩充图G:先扩充V,在原有地图的外围加一圈顶点:v00, v01, …, v0,M+1,vN+1,0, vN+1,1, …, vN+1,M+1,v10, v20, …, vN0,v1,M+1, v2,M+1, …, vN,M+1。新顶点的矿藏价值为0。再相应扩充E,所有原来地图边缘顶点与这些新顶点连边。

     

    设整个地图的矿藏总值为A,Mr.Chen领地(不含v00)中的矿藏价值为AS,剩下部分的矿藏价值为AT,则AS+AT=A。求S有两条途径:

         (a) 遍历不含v00的子图S,直接统计AS

         (b) 遍历含v00的子图T,统计AT,由AS=A-AT求出AS,其中A可通过两重循环简单求得。

    如果用(a)计划,必须需要先找到S中的一个顶点,然后开始遍历,要做到这一点比较困难。相比之下,如果用(b)计划,可直接从v00开始遍历,省去不少麻烦,所以我们用(b)计划。

     

    种子染色法可以形象的理解为在图中抛下一颗种子(顶点v00),一种颜色就朝着四面八方蔓延开来,填满所有可达区域。我们用队列q存储非Mr.Chen领地中待扩展单位区域的坐标,按照“先进先出”的顺序扩展这些单位区域,直至队列q空为止。此时,非Mr.Chen领地的区域全部被染色,矿藏总值A减去被染色区域内的矿藏价值即为问题的解。

    设地图的行数为N,列数为M,地图为a,其中单位区域(r,c) 中的矿藏价值为a[r,c]。如果 (r,c)为边界,则a[r,c]=‘*’。写程序时也你可以用某个特殊的数代替‘*’,例如-1。

     

     1 Readln(n,m);                          /*输入地图信息*/
     2 for c←1 to n do
     3 for r←1 to m do read(read(a[c,r]);
     4 /*设边缘顶点的矿藏价值为0*/
     5 for c←0 to M+1 do{a[0,c]←0;a[N+1,c]←0 } 6 for r←1 to N do {a[r,0]←0;a[r,M+1]←0} 7 A←0;                         /*累计个地图的矿藏总值*/
     8 for r←1 to N do
     9  for c←1 to M do if a[r,c] ‘*’ then A←A+a[r,c];
    10 (0,0)进入队列q;
    11 while  q队列非空do
    12  { 取出q的队首坐标(r,c);
    13     SUB-Test(r-1,c);SUB-Test(r+1,c);/*依次处理(r,c)的4个相邻位置*/
    14     SUB-Test(r,c-1);SUB-Test(r,c+1);
    15     q出队操作 };/*while*/
    16 writeln(A);
    17 其中过程SUB-Test(r,c)判断区域(r,c)是否在地图外或为边界。如果不是,则入队,并从A中扣去该区域矿藏价值,同时置已访问标志”*”。
    18 Proc SUB-Test(r,c:integer);
    19 {  if(r0)and(c0)and(rN+1)and(cM+1)and(a[r,c]‘*’)
    20        then{ (r,c)进入队列q;A←A-a[r,c];a[r,c]←‘*’}/*then*/
    21 }/* SUB-Test */

     

  • 相关阅读:
    [转]用mamcache 存储session的好处
    [转]怎么写 JQuery插件 (案例原理)
    关于查询优化
    HBase Canary
    HBase Bulk Loading
    有用的技术网站
    HBase 运维分析
    HBase rest
    hbase mlockall
    Jamon
  • 原文地址:https://www.cnblogs.com/huashanqingzhu/p/7625858.html
Copyright © 2011-2022 走看看