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行代码满满的是泪。。。

				
时间: 2024-12-21 06:08:55

P1101 单词方阵【洛谷】的相关文章

Luogu P1101 单词方阵

明明是一道水题,我还找不出 bug 来...原本在 DFS 途中记录单词串,只好使用笨方法,在结尾加一个 for 记录单词串.终于过了. 思路:枚举图中每一个点进行 DFS,途中判断访问的点是否为连续元素("yizhong"字符串中连续),如果不是返回:进行下一层 DFS,如果返回值 True 则直接层层返回 True,强行退出. 1 /* P1101 单词方阵 2 * Au: GG 3 */ 4 #include <cstdio> 5 #include <cstdl

洛谷——P1101 单词方阵

https://www.luogu.org/problem/show?pid=1101#sub 题目描述 给一nXn的字母方阵,内可能蕴含多个“yizhong”单词.单词在方阵中是沿着同一方向连续摆放的.摆放可沿着8个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间[color=red]可以[/color]交叉,因此有可能共用字母.输出时,将不是单词的字母用“*”代替,以突出显示单词.例如: 输入: 8 输出: qyizhong *yizhong gydthkjy gy****** n

洛谷P1101 单词方阵——S.B.S.

题目描述 给一nXn的字母方阵,内可能蕴含多个“yizhong”单词.单词在方阵中是沿着同一方向连续摆放的.摆放可沿着8个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间[color=red]可以[/color]交叉,因此有可能共用字母.输出时,将不是单词的字母用“*”代替,以突出显示单词.例如: 输入: 8 输出: qyizhong *yizhong gydthkjy gy****** nwidghji n*i***** orbzsfgz o**z**** hhgrhwth h***

洛谷 P1101 单词方阵

不算搜索的搜索 思路和很多人的一样,因为只要找到两个字母,方向就确定了,记录下方向,剩下的暴力即可. #include<iostream> #include<cstdio> #include<algorithm> using namespace std; int n; int fx[9][2]={{0,0},{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}};//存方向,循环起来比较方便 char map[101

落谷P1101 单词方阵 //参考代码

1 #include<iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int N = 105; 6 char s[N][N], a[] = "yizhong"; 7 bool vis[N][N]; 8 int n; 9 int dx[8] = {0, 0, 1, -1, 1, 1, -1, -1}, 10 dy[8] = {1, -1,

落谷P1101 单词方阵 //未完成

1 #include<iostream>/*cout<<endl; 2 for(int i=1;i<=n;i++) 3 for(int j=0;j<n;j++){ 4 5 cout<<a[i][j]; 6 if(j==n-1)cout<<endl; 7 }*/ 8 #include<cstring> 9 #include<cstdio> 10 using namespace std; 11 const int wd=101

P1101 单词方阵 简单dfs

题目描述 给一n \times nn×n的字母方阵,内可能蕴含多个“yizhong”单词.单词在方阵中是沿着同一方向连续摆放的.摆放可沿着 88 个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间可以交叉,因此有可能共用字母.输出时,将不是单词的字母用*代替,以突出显示单词.例如: 输入: 8 输出: qyizhong *yizhong gydthkjy gy****** nwidghji n*i***** orbzsfgz o**z**** hhgrhwth h***h*** zzz

P1101 单词方阵

题目描述:给一n×n的字母方阵,内可能蕴含多个“yizhong”单词.单词在方阵中是沿着同一方向连续摆放的.摆放可沿着 8 个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间可以交叉,因此有可能共用字母.输出时,将不是单词的字母用*代替,以突出显示单词.例如: 输入: 8 输出: qyizhong *yizhong gydthkjy gy****** nwidghji n*i***** orbzsfgz o**z**** hhgrhwth h***h*** zzzzzozo z****

洛谷P1019 单词接龙

P1019 单词接龙 题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连. 输入输出格式 输入格式: 输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,