zoukankan      html  css  js  c++  java
  • P1101 单词方阵【洛谷】

    //题目-----------------------------------------------------------------------------------------

    传送门: http://www.luogu.org/problem/show?pid=1101

    P1101 单词方阵

    题目描述

    给一nXn的字母方阵,内可能蕴含多个“yizhong”单词。单词在方阵中是沿着同一方向连续摆放的。摆放可沿着8个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间[color=red]可以[/color]交叉,因此有可能共用字母。输出时,将不是单词的字母用“*”代替,以突出显示单词。例如:

    输入:
        8                     输出:
        qyizhong              *yizhong
        gydthkjy              gy******
        nwidghji              n*i*****
        orbzsfgz              o**z****
        hhgrhwth              h***h***
        zzzzzozo              z****o**
        iwdfrgng              i*****n*
        yyyygggg              y******g

    输入输出格式

    输入格式:

    第一行输入一个数n。(7<=n<=100)。

    第二行开始输入nXn的字母矩阵。

    输出格式:

    突出显示单词的nXn矩阵。

    输入输出样例

    输入样例#1:
    7
    aaaaaaa
    aaaaaaa
    aaaaaaa
    aaaaaaa
    aaaaaaa
    aaaaaaa
    aaaaaaa
    
    输出样例#1:
    *******
    *******
    *******
    *******
    *******
    *******
    *******


    //解题--------------------------------------------------------------------------------

    【题解区似乎没人用这方法,虽然不是最优。。不过憋了一个多小时没看题解,苦苦debug后终于AC的这感觉。。。
    首先在看到这东西时,根本不觉得是DFS【QAQ】,后来想尽方法把它和DFS扯上关系,终于得出了一个奇葩的方法:
    .     因为yizhong里每个字母都是独一无二的,所以
    .           可以将他们与1,2,3,4,5,6,7一一对应,
    .                  即: 1---y, 2---i, 3---z, 4---h, 5---o, 6---n, 7---g


    //注:以下说到的层,是指搜索树的每一层【就是DFS里面的深度】
    1.  以每行一个string的形式读入数据并转存该方阵到二维布尔数组,
    .    将每一个在‘yizhong’里面的字母的坐标分别存在rx和ry,count[i]为该字母的个数;
    2. 一层层try,找每一层即找‘yizhong’里的每一个字母(第一层找y,第二层找i,第三层找z……)
    .    怎么找呢? 这时就要用的rx和ry啦 如果对应的坐标能够通过检查,就找下一层(当深度小于7时)
    .         关于这里的检查: 用到一个过程checkfirst和一个函数check,
    .              因为如果找到yi,那么就大致确定了这个yizhong的方向,checkfirst就是这个功能而且顺带判断可不可用
    .               check呢,就是判断这个字母是不是在和前面的在同一直线,且相邻
    .   这样找的话,
    .           如果能找到第七层(yizhong长7)就说明找到了一个‘yizhong’,
    .            此时就调用chuli过程进行处理(即把ju数组里面的相应位置标记用于输出时判断)
    3.   输出时,如果ju数组中的元素为false【说明是yizhong的一部分】就输出它本身,否则输出*



    //代码---------------------------------------------------------------------------------

    program dancifangzhen;
    //-----------------------------------------------------------------
    const
        //  1---y,    2---i,    3---z,    4---h,    5---o,   6---n,   7---g
        bian:array['g'..'z'] of integer=(7,4,2,0,0,0,0,6,5,0,0,0,0,0,0,0,0,0,1,3);
    //-----------------------------------------------------------------
    var
       n,i,j,lx,ly,pull:longint;
       t:char;
       count:array[1..7] of integer;
       rx,ry:array[1..7,1..10000] of integer;
       ju:array[1..100,1..100] of boolean;
       ans:array[1..7,1..2] of integer;
       inin:set of char;
       inp:array[1..100,1..100] of char;
       st:string;
    //-----------------------------------------------------------------
    procedure chuli;
    var
       z:longint;
    begin
       for z:=1 to 7 do
         ju[ans[z,1],ans[z,2]]:=false;          //对应的标记为false
    end;
    //-----------------------------------------------------------------
    procedure checkfirst(a,b:longint);
    begin
        pull:=0;
        if (a-lx<-1) or (a-lx>1) then exit;    //不在其上一行,下一行或同一行
        if (b-ly<-1) or (b-ly>1) then exit;    //不在其左一列,有一列或同一列
        if (lx=a) then pull:=1;//1表示在同一行
        if (ly=b) then pull:=2;//2表示在同一列
        if (lx+ly=a+b) then pull:=3;//3表示在同一 ‘/’ 斜线
        if (ly-lx=b-a) then pull:=4;//4表示在同一 ‘ ’斜线
    
    end;
    //-----------------------------------------------------------------
    function check(a,b:longint):boolean;
    begin
        if (a-lx<-1) or (a-lx>1) then exit(false);   //不在其上一行,下一行或同一行
        if (b-ly<-1) or (b-ly>1) then exit(false);   //不在其左一列,有一列或同一列
        if pull=1 then if a<>lx then exit(false);//1----if pull=2 then if b<>ly then exit(false);//2----if pull=3 then if lx+ly<>a+b then exit(false);//3---- ‘/’ 斜线
        if pull=4 then if ly-lx<>b-a then exit(false);//4---- ‘’ 斜线
        exit(true);
    end;
    //-----------------------------------------------------------------
    procedure try(d:longint);
    var
      i,x,y:longint;
    begin
       for i:= 1 to count[d] do
       begin
         x:=rx[d,i];
         y:=ry[d,i];
         if d<>1 then begin                              //第一个没有前一个字母
                         lx:=ans[d-1,1];  
                 ly:=ans[d-1,2];  //记录前一个字母
                      end;
         if d=2 then begin
                       checkfirst(x,y);//第二次才开始要判断
                       if pull=0 then continue;
               //pull等于0时表示它不在上一个的任意一条对角线或横纵线上
                     end;
         if (d>2) and (check(x,y)=false) then continue;  //没通过检查
         ans[d,1]:=x;   ans[d,2]:=y;                     //记录
         if d<7 then try(d+1)                            //还没找完一个继续try
            else chuli;                                  //找完一个就处理
       end;
    end;
    //-----------------------------------------------------------------
    begin
       inin:=['y','i','z','h','o','n','g'];            //‘yizhong’集合
       fillchar(ju,sizeof(ju),true);
       readln(n);
       for i:= 1 to n do
         begin
           readln(st);                           //字符串读入比较好,字符很容易出错
           for j:= 1 to length(st) do
           begin
              inp[i,j]:=st[j];
              t:=st[j];
              if t in inin then begin
                                    inc(count[bian[t]]);
                                    rx[bian[t],count[bian[t]]]:=i;
                                    ry[bian[t],count[bian[t]]]:=j;
                                end;
           end;
         end;
       try(1);
       for i:= 1 to n do
       begin
         for j:= 1 to n do                         //输出过程
          if ju[i,j] then write('*')
            else write(inp[i,j]);
         writeln;
       end;
    end.

    //99行代码满满的是泪。。。





  • 相关阅读:
    爬虫介绍
    HTTP请求协议
    谷歌浏览器表单提交,input填充背景
    SVN与GIT基础知识学习
    vue 开发环境搭建
    正则表达式验证
    canvas基础
    数组基础方法应用
    AJAX基础学习
    css弹性布局 --flex布局。
  • 原文地址:https://www.cnblogs.com/bobble/p/5929503.html
Copyright © 2011-2022 走看看