洛谷 P1101 单词方阵

AC的代码在最下面啦。

是C++的,上面用的都是C。

 

第一次的错误代码:

#include<stdio.h>
int n;
char zm[100][100];//输入的单词矩阵 
char a[8]="yizhong";

int xx[]={1,1,1,0,0,-1,-1,-1};
int yy[]={1,0,-1,1,-1,1,0,-1};
//八个摆放的方向 
int vis[100][100];//标记 
int mp[100][100];//染色 

void dfs(int x,int y)
{
	for(int i=0;i<8;i++)//八个方向 
	{
		for(int j=0;j<7;j++)//七个字母,即yizhong 
		{
			int nx = x + j*xx[i];
			int ny = y + j*yy[i];
			if(zm[nx][ny] == a[x])
			{
			    vis[nx][ny]=1;
			}
			else
			{
				vis[100][100]={0};
			}
		}
	}
	
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(vis[i][j] == 1)
			{
				mp[i][j] == 1;//确保vis数组在清0之后已经被突出显示的单词不会被影响 
			}
		}
	 } 
}

int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			scanf("%c",&zm[i][i]);
		}
	}
	
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(zm[i][j] == 'y')//找到首字母'y' 
			{
				dfs(i,j);//从第i行第j列的字母'y'开始搜索 
			}
		}
	}
	
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(mp[i][j]==1)
			{
				printf("%c",zm[i][j]);
			}
			else
			{
				printf("*");
			}
		}
		printf("\n");
	}
	return 0;
}

昨天写的,很急躁,写的挺混乱

今天写的:

一开始连输入输出那块都有问题,代码看着没问题,不知道运行的时候输入输出有问题

 这是没有getchar()的情况

 这里没有getchar,第二重循环不加=

 真的很迷,这个输出结果

 然后这加了getchar,还是很迷

 


两处都改动后,虽然结果不对,只凸显出一个yizhong,但是输出的那块倒是和输入的是一样的,没有乱行的情况了,'y'的坐标(i,j)也都对上了,不知道为什么会有这种情况

然后这里改成n=4,输入矩阵,打印出来的矩阵和y坐标也都对了,突显的结果不对,但格式也没问题了,所以这块输入输出应该没问题了,主要看看dfs函数有没有什么遗漏和问题
 

总觉得这块还是有问题

感觉dfs函数这边也没啥问题了,但是只有一个yizhong凸显出来

而且还是斜的那个,正好是第一重循环,i=0搜索(1,1),即左上往右下的方向,正好就是凸显出来的那条,不对,搜到的第一个y应该是第一行横着的那个才对

那有可能循环就没往后进行下去或者也可能是别的问题,先把目前为止的代码记录一下

#include<stdio.h>
int n;
char zm[100][100];//输入的单词矩阵 
char a[8]="yizhong";

int xx[]={1,1,1,0,0,-1,-1,-1};
int yy[]={1,0,-1,1,-1,1,0,-1};
//八个摆放的方向 
int vis[100][100];//标记

void dfs(int x,int y)
{
	int k=1;//用于判断是否出现yizhong 
	//printf("k=%d\n",k);
	for(int i=0;i<8;i++)//由找到的'y'开始,搜索它的八个方向 
	{
		for(int j=0;j<7;j++)//该方向上从'y'开始七个字母,即yizhong 
		{
			int nx = x + j*xx[i];
			int ny = y + j*yy[i];
			if(zm[nx][ny] == a[j] &&nx>=1&&nx<=n&&ny>=1&&ny<=n)//判断,考虑边界 
			{
			    continue;
			}
			else
			{
				k=0;
				break; //从这个方向上过去所有的字母都必须与yizhong对应,否则内部循环停止k=0 
			}
		}
		if(k == 1)//k=1说明找到yizhong,将其标记并输出 
		{
			for(int j=0;j<7;j++)
			{
				int nx = x + j*xx[i];
			    int ny = y + j*yy[i];
			    vis[nx][ny]=1;
			}
		}
	}
}

int main()
{
	scanf("%d",&n);
	getchar();
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<=n;j++)
		{
			scanf("%c",&zm[i][j]);
		}
	}
	/*for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			printf("%c",zm[i][j]);
		}
		printf("\n");
	}//输出看下输入的格式对不对*/ 
	
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(zm[i][j] == 'y')//找到首字母'y' 
			{
				printf("i=%d,j=%d\n",i,j);
				dfs(i,j);//从第i行第j列的字母'y'开始搜索 
			}
		}
	}
	
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(vis[i][j]==1)
			{
				printf("%c",zm[i][j]);
			}
			else
			{
				printf("*");
			}
		}
		printf("\n");
	}
	return 0;
}


这里把j=0改成了j=1,没什么影响,就从y开始遍历变成了从i开始,缩短了时间
把int k=1移入了了第一重循环,因为如果k=1在外面,那第一次不对,下面每次i++循环就都是k=0,根本得不出结果
但是运行了一下还是不对,结果还是不对

 


这里把搜索步骤都打印了出来
只有搜索坐标为(1,1)的那个'y'的时候,搜索i=0的方向,即(1,1)方向左下角,k=1,可以凸显出yizhong,而搜索别的y坐标的八个方向k都=0
而本来(0,1)处的y的i=4即(0,1)方向,和(7,0)处的y的(-1,0)方向的k都应该=0并打印出一中的
那就把printf("   i=%d,k=%d\n",i,k);再移到内重循环里再检查一下问题出在哪,加上个j=%d

 

 上面i=0,j=0下面应该是(0,1)指向i=3,j=1,k=0那行,画错了,指向i=4去了

 

 

 这下对了!

果然不耐心下来做不出题


。。。。。。。。。


我@¥%*&%%¥……#

 

又测试了两组数据,没毛病啊。。

可能问题是出在一开始就有问题的输入输出那边了 

我闲的没事改成了C++

 

改成C++交上去对了。。。。。。。。我不理解。。

#include<iostream>
using namespace std;
int n;
char zm[100][100];
char a[8]="yizhong";

int xx[]={1,1,1,0,0,-1,-1,-1};
int yy[]={1,0,-1,1,-1,1,0,-1};
int vis[100][100];//标记

void dfs(int x,int y)
{
	for(int i=0;i<8;i++)//由找到的'y'开始,搜索它的八个方向 
	{
    	int k=1;//用于判断是否出现yizhong 
		for(int j=1;j<7;j++)//该方向上从'y'开始七个字母,即yizhong 
		{
			int nx = x + j*xx[i];
			int ny = y + j*yy[i];
			if(zm[nx][ny] == a[j] &&nx>=0&&nx<n&&ny>=0&&ny<n)//判断,考虑边界 
			{
			    //printf("   i=%d,j=%d,k=%d\n",i,j,k);
			    continue;
			}
			else
			{
				k=0;
				//printf("   i=%d,j=%d,k=%d\n",i,j,k);
				break; //从这个方向上过去所有的字母都必须与yizhong对应,否则内部循环停止k=0 
			}
		}
		if(k == 1)//k=1说明这个方向上找到yizhong,将其标记并输出 
		{
			for(int j=0;j<7;j++)
			{
				int nx = x + j*xx[i];
			    int ny = y + j*yy[i];
			    vis[nx][ny]=1;
			}
		}
	}
}

int main()
{
	cin>>n;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			cin>>zm[i][j];
		}
	}
	
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(zm[i][j] == 'y')//找到首字母'y' 
			{
				//printf("i=%d,j=%d\n",i,j);
				dfs(i,j);//从第i行第j列的字母'y'开始搜索 
			}
		}
	}
	
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(vis[i][j]==1)
			{
				cout<<zm[i][j];
			}
			else
			{
				cout<<'*';
			}
		}
		cout<<endl;
	}
	return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值