2022/1/12总结

又是摸鱼的一天,尽管学了很久(12h),但是感觉没怎么写出来题目:

链表还是没做出来,可惜。

今天把搜索只做了1题,其他的真的做不下去,没有思路qwq。除了八皇后,但是自己试了dfs和bfs发现样例都不对... ...陆陆续续做了几个小时,然后决定放弃了。

今天我书到了,《大话数据结构》,看了下,还没有很深入。今天大部分时间都花在了B站关于搜索的教程和一些其他C++教程上,感觉杂七杂八的感觉都接触了一下,但不是很懂Orz。


题目描述

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

输入:
    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)。

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

输出格式

突出显示单词的n×n矩阵。

输入输出样例

输入 #1复制

7
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa

输出 #1复制

*******
*******
*******
*******
*******
*******
*******

输入 #2复制

8
qyizhong
gydthkjy
nwidghji
orbzsfgz
hhgrhwth
zzzzzozo
iwdfrgng
yyyygggg

输出 #2复制

*yizhong
gy******
n*i*****
o**z****
h***h***
z****o**
i*****n*
y******g

这道题比较明显,用dfs做。就是一个方向的遍历和回溯标记。我是采用了'y'为起点,'g'为终点,往一个方向走连续标记,当一个方向的起点到终点能构成‘yizhong’则不取消标记,如果单词顺序不对,即‘碰壁’则回溯取消标记,遍历整个地图。当遍历完成后,再遍历输出问题,将标记的格子输出原来的内容,没有标记的则输出‘*’,我其实感觉我写的代码还是有点麻烦,但是也想不到其他方法了,光这个就花了我2个多小时Orz。下面上AC代码:

#include <bits/stdc++.h>

using namespace std;

char mp[105][105];
int vis[105][105] = {0};
int me[105][105] = {0};
char cmp[7] = {'y', 'i', 'z', 'h', 'o', 'n', 'g'};

int dx[8] = {0, 0, -1, 1, 1, 1, -1, -1};
int dy[8] = {1, -1, 0, 0, 1, -1, -1, 1};
int n;

bool CanCon = false;
int CanCondi = -1;

void dfs(int px, int py, int direction);

int main()
{
	ios::sync_with_stdio(false);
	memset(mp, NULL, 105 * 105);
//	string ns;
//	getline(cin, ns, '\n');
//	for(int i = 0;i < ns.size();i ++)
//	{
//		n = n * 10 + (ns[i] - '0');
//	}
	cin >> n;
//	getchar();
	string tmp;
	for(int i = 1;i <= n;i ++)
	{
		cin >> tmp;
//		cout << tmp << endl;
		for(int j = 0;j < tmp.size();j ++)
		{
			mp[i][j + 1] = tmp[j];
		}
//		cout << mp[i][0] << endl;
	}
//	cout << endl;
//	for(int i = 1;i <= n;i ++)
//	{
//		{
//			for(int j = 1;j <= n;j ++)
//			{
//				cout << mp[i][j];
//			}
//			cout << endl;
//		}
//	}
//	cout << endl;
	for(int i = 1;i <= n;i ++)
	{
		for(int j = 1;j <= n;j ++)
		{
			if(mp[i][j] == cmp[0] && vis[i][j] != 1)
			{
				vis[i][j] = 1;
				dfs(i, j, -1);
				if(CanCon) me[i][j] = 1;
			}
		}
	}
	for(int i = 1;i <= n - 1;i ++)
	{
		for(int j = 1;j <= n;j ++)
		{
			if(me[i][j])
			{
				cout << mp[i][j];
			}
			else
			{
				cout << '*';
			}
		}
		cout << endl;
	}
	for(int j = 1;j <= n;j ++)
	{
		if(me[n][j])
		{
			cout << mp[n][j];
		}
		else
		{
			cout << '*';
		}		
	}
	return 0;
}

void dfs(int px, int py, int direction)
{
	char c = mp[px][py];
	if(c == 'g')
	{
		CanCon = true;
		CanCondi = direction;
		return;
	}
	int num = 0;
	for(int i = 0;i < 7;i ++)
	{
		if(c == cmp[i])
		{
			num = i;
			break;
		}
	}
	int nx, ny;
	if(direction == -1)
	{
		CanCon = false;
		CanCondi = -1;
		for(int i = 0;i < 8;i ++)
		{
			nx = px + dx[i];
			ny = py + dy[i];
			if(mp[nx][ny] == cmp[num + 1] && nx >= 1 && nx <= n && ny >= 1 && ny <= n)
			{
				vis[nx][ny] = 1;
//				cout << "goto " << mp[nx][ny] << ":" << nx << ", " << ny << " from " << mp[px][py] << ":" << px << ", " << py << endl;
				dfs(nx, ny, i);
				if(!CanCon && me[nx][ny] != 1) vis[nx][ny] = 0;
				else if(CanCon && CanCondi == i) me[nx][ny] = 1;
			}
		}	
	}
	else
	{
		nx = px + dx[direction];
		ny = py + dy[direction];
		if(mp[nx][ny] == cmp[num + 1] && nx >= 1 && nx <= n && ny >= 1 && ny <= n)
		{
			vis[nx][ny] = 1;
//			cout << "goto " << mp[nx][ny] << ":" << nx << ", " << ny << " from " << mp[px][py] << ":" << px << ", " << py << endl;
			dfs(nx, ny, direction);
			if(!CanCon && me[nx][ny] != 1) vis[nx][ny] = 0;
			else if(CanCon && CanCondi == direction) me[nx][ny] = 1;
		}
	}
}

明天可以再看看书吧,然后看看能不能把八皇后解决了哦。B站教程,在找到比较适合收藏长久的比较系统的教程前,还是不看了吧 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ISansXI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值