单词方阵

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

输入样例#2: 复制
8
qyizhong
gydthkjy
nwidghji
orbzsfgz
hhgrhwth
zzzzzozo
iwdfrgng
yyyygggg
输出样例#2: 复制
yizhong
gy
*****
ni*****
oz
***
hh***
z
o**
i*****n

y
****g

开始时候没看到要同一方向的code

#include<algorithm>
#include<cstdio>
using namespace std;
string  key="yizhong";
char dt[110][110];
int vis[110][110];
int m;
struct node{
	int x;
	int y;
}que[7];
void dfs (int x,int y,int n){
	int i,j,dx,dy;
	
	if(n==7){if(dt[x][y]=='g') {
		for(i=0;i<7;i++){
			vis[que[i].x ][que[i].y ]=1;
		}
	}
		
		return ;
	}
	else{
		for(i=-1;i<=1;i++){
			for(j=-1;j<=1;j++){
				dx=x+i;
				dy=y+j;
				if(dx<=m&&dx>=1&&dy<=m&&dy>=1&&key[n]==dt[dx][dy]){
					que[n].x=dx;
					que[n].y=dy;
					dfs(dx,dy,n+1);
				}
			}
		}
		
	}
	return ;
}
int main(){
	scanf("%d",&m);
	int i,j;
	for(i=1;i<=m;i++){
		getchar();
		for(j=1;j<=m;j++){
			scanf("%c",&dt[i][j]);
		}
	}
	for(i=1;i<=m;i++){
		for(j=1;j<=m;j++){
			if(dt[i][j]=='y'){
				que[0].x =i;
				que[0].y =j;
				dfs(i,j,1);
			}
		}
	}
	for(i=1;i<=m;i++){
		for(j=1;j<=m;j++){
			if(vis[i][j]==1){
				printf("%c",dt[i][j]);
			}else printf("*");
		}
		printf("\n");
	}
	
}

一下的代码from https://www.luogu.org/problemnew/solution/P1101
AC 如下

#include<iostream>
using namespace std;
int n,u[8]={0,-1,-1,-1,0,1,1,1},v[8]={1,1,0,-1,-1,-1,0,1};//八个方向
char le[200],chess[101][101];
bool ma[101][101];
bool DFS(int x,int y,char w,int p){//我在哪,我是什么字母,我现在的方向是哪
    if(w=='g'){//最后一个字母判断成功,标记,返回
        ma[x][y]=1;
        return 1;
    }
    int xx=x+u[p],yy=y+v[p];
    if(xx>=1 && yy>=1 && xx<=n && yy<=n && chess[xx][yy]==le[w])//搜索,不解释
    if(DFS(xx,yy,le[w],p)){
        ma[x][y]=1;
        return 1;
    }
    return 0;
}
int main(){
    le['y']='i';
    le['i']='z';
    le['z']='h';
    le['h']='o';
    le['o']='n';
    le['n']='g';//把单词串在一起
    cin>>n;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    cin>>chess[i][j];
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    if(chess[i][j]=='y')//如果是单词开头
    for(int k=0;k<=7;k++)//就八个方向搜索
    if(DFS(i,j,'y',k)) ma[i][j]=1; //判断是否成单词
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++)
        if(ma[i][j]) cout<<chess[i][j];
        else cout<<'*';
        cout<<endl;
    }
    return 0;
}

WA 了好久 嗯似乎是洛谷平台对读入的一些要求的原因,然后稍微改了以下读入 就AC了 原来的WA在最后面(其实输出和样例明明完全一样的额)

(所以下次还是直接从坐标为 0 开始读入吧

#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
char  key[]="yizhong";
char dt[110][110];
int vis[110][110];
int m;
int xx[8]={1,1,0,1,0,-1,-1,-1};
int yy[8]={1,-1,1,0,-1,-1,1,0};
struct node{
	int x;
	int y;
}que[7];
void dfs (int x,int y,int n,int dir){
	int i,dx,dy;
	
	if(n==7){if(dt[x][y]=='g') {
		for(i=0;i<7;i++){
			vis[que[i].x ][que[i].y ]=1;
		}
	}

	}
	else if(dir==-1){
		for(i=0;i<8;i++){
			
				dx=x+xx[i];
				dy=y+yy[i];
				if(dx<m&&dx>=0&&dy<m&&dy>=0&&key[n]==dt[dx][dy]){
					que[n].x=dx;
					que[n].y=dy;
					dfs(dx,dy,n+1,i);
				}
			
		}
		
	}else {
			dx=x+xx[dir];
			dy=y+yy[dir];
				if(dx<m&&dx>=0&&dy<m&&dy>=0&&key[n]==dt[dx][dy]){
					que[n].x=dx;
					que[n].y=dy;
					dfs(dx,dy,n+1,dir);
				}
	}
}
int main(){
	scanf("%d",&m);
	int i,j;
	for(i=0;i<m;i++){
	scanf("%s",dt[i]);
	}
	for(i=0;i<m;i++){
		for(j=0;j<m;j++){
			if(dt[i][j]=='y'){
				que[0].x =i;
				que[0].y =j;
				dfs(i,j,1,-1);
			}
		}
	}
	for(i=0;i<m;i++){
		for(j=0;j<m;j++){
			if(vis[i][j]==1){
				cout<<dt[i][j]; 
			}else cout<<'*';
		}
		cout<<endl;
	}
	
}
 
#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
char  key[]="yizhong";
char dt[110][110];
int vis[110][110];
int m;
int xx[8]={1,1,0,1,0,-1,-1,-1};
int yy[8]={1,-1,1,0,-1,-1,1,0};
struct node{
    int x;
    int y;
}que[7];
void dfs (int x,int y,int n,int dir){
    int i,dx,dy;

    if(n==7){if(dt[x][y]=='g') {
        for(i=0;i<7;i++){
            vis[que[i].x ][que[i].y ]=1;
        }
    }

    }
    else if(dir==-1){
        for(i=0;i<8;i++){

                dx=x+xx[i];
                dy=y+yy[i];
                if(dx<=m&&dx>=1&&dy<=m&&dy>=1&&key[n]==dt[dx][dy]){
                    que[n].x=dx;
                    que[n].y=dy;
                    dfs(dx,dy,n+1,i);
                }

        }

    }else {
            dx=x+xx[dir];
            dy=y+yy[dir];
                if(dx<=m&&dx>=1&&dy<=m&&dy>=1&&key[n]==dt[dx][dy]){
                    que[n].x=dx;
                    que[n].y=dy;
                    dfs(dx,dy,n+1,dir);
                }
    }
}
int main(){
    scanf("%d",&m);
    int i,j;
    for(i=1;i<=m;i++){
        getchar();
        for(j=1;j<=m;j++){
            scanf("%c",&dt[i][j]);
        }
    }
    for(i=1;i<=m;i++){
        for(j=1;j<=m;j++){
            if(dt[i][j]=='y'){
                que[0].x =i;
                que[0].y =j;
                dfs(i,j,1,-1);
            }
        }
    }
    for(i=1;i<=m;i++){
        for(j=1;j<=m;j++){
            if(vis[i][j]==1){
                cout<<dt[i][j]; 
            }else cout<<'*';
        }
        cout<<endl;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值