当前位置: 首页 > news >正文

蓝桥云客 数字接龙

2.数字接龙 - 蓝桥云课

问题描述

小蓝最近迷上了一款名为《数字接龙》的迷宫游戏,游戏在一个大小为 N×N 的格子棋盘上展开,其中每一个格子处都有着一个 0…K−1 之间的整数。游戏规则如下:

  1. 从左上角 (0,0) 处出发,目标是到达右下角 (N−1,N−1) 处的格子,每一步可以选择沿着水平/垂直/对角线方向移动到下一个格子。
  2. 对于路径经过的棋盘格子,按照经过的格子顺序,上面的数字组成的序列要满足:0,1,2,…,K−1,0,1,2,…,K−1,0,1,2,…。
  3. 途中需要对棋盘上的每个格子恰好都经过一次(仅一次)。
  4. 路径中不可以出现交叉的线路。例如之前有从 (0,0) 移动到 (1,1),那么再从 (1,0) 移动到 (0,1) 线路就会交叉。

为了方便表示,我们对可以行进的所有八个方向进行了数字编号,如下图2所示;因此行进路径可以用一个包含 0…7 之间的数字字符串表示,如下图1是一个迷宫示例,它所对应的答案就是:41255214。

输入格式
第一行包含两个整数 N, K。
接下来输入 N 行,每行 N 个整数表示棋盘格子上的数字。

输出格式
输出一行表示答案。如果存在答案输出路径,否则输出 -1。

样例输入
 

3 3
0 2 0
1 1 1
2 0 2

样例输出
 

41255214

样例说明
行进路径如图 1 所示。

评测用例规模与约定
对于 80% 的评测用例: 1 ≤ N ≤ 5。
对于 100% 的评测用例: 1 ≤ N ≤ 10, 1 ≤ K ≤ 10。

思路:

75%无判断交叉的代码

代码:

#include <bits/stdc++.h>
using namespace std;
  		 // 0   1   2  3  4  5  6   7
int dx[] = {-1, -1, 0, 1, 1, 1, 0, -1};
int dy[] = {0, 1, 1, 1, 0, -1, -1, -1};
int n,k;
int a[15][15];
bool found;
bool vis[15][15];
vector <int> num;
unordered_map <int,int> mp;
bool check(int x,int y,int kx,int ky)
{
	if(vis[x+kx][y] && vis[x][y+ky])//如果这两个点为真,那么就是斜线 
	return false;
	else
	return false;
}
void dfs(int x,int y,int step,int cnt)
{
	if(found)
	return;
	if(x == n && y == n)
	{
		if(step == n*n)
		{
			found = true;
			for(int j = 0 ; j < num.size() ; j++)
			cout << num[j];
			return;	
		}
	}  
	for(int i = 0 ; i < 8 ; i++)
	{
		int tx = x + dx[i];
		int ty = y + dy[i];
	/*	if(mp[dx[i]*8+dy[i]]== 1 || mp[dx[i]*8+dy[i]]== 3 || mp[dx[i]*8+dy[i]]== 5 || mp[dx[i]*8+dy[i]]== 7) //判断斜线 
		{
			if(check(tx,ty,dx[i],dy[i])) 
			continue; 
		}*/
		if(!vis[tx][ty] && tx >= 1 && tx <= n && ty >=1 && ty <= n && a[tx][ty] == cnt)
		{
			vis[tx][ty] = true;
			num.push_back(mp[dx[i]*8+dy[i]]);
			dfs(tx,ty,step+1,(cnt+1)%k);
			vis[tx][ty] = false;
			num.pop_back();
		}
	}

}
int main()
{
	cin >> n >> k;
	for(int i = 1 ; i <= n ; i++)
	{
		for(int j = 1 ; j <= n ; j++)
		{
			cin >> a[i][j];
		}
	}
	for(int i = 0 ; i < 8 ; i++)
	{
//		cout <<"dx[i]*dy[i] :" << dx[i]*8+dy[i] <<"----------------mp[dx[i]*8+dy[i]]] :" << 	mp[dx[i]*8+dy[i]] << endl;
		mp[dx[i]*8+dy[i]] = i;
	}
	vis[1][1] = true; 
	dfs(1,1,1,1);
	if(found)
	{

	}
	else
	cout << -1;
  	return 0;
}

思路:

利用图论知识,将边连接起来,然后就可以判断是否有交叉,点的话,将二维转化为一维作为点的下标。记得数组要开大点。

代码:

#include <bits/stdc++.h>
using namespace std;
  		 // 0   1   2  3  4  5  6   7
int dx[] = {-1, -1, 0, 1, 1, 1, 0, -1};
int dy[] = {0, 1, 1, 1, 0, -1, -1, -1};
int n,k;
int a[15][15];
bool found;
bool vis[15][15];
bool attached[500][500]; 
vector <int> num;
unordered_map <int,int> mp;
bool check(int x,int y,int kx, int ky)
{
	if(attached[(x+kx)*10+y][x*10+(y+ky)])//如果这两个点为真,那么就是交叉 
	return true;
	else
	return false;
}
void dfs(int x,int y,int step,int cnt)
{
	if(found)
	return;
	if(x == n && y == n)
	{
		if(step == n*n)
		{
			found = true;
			for(int j = 0 ; j < num.size() ; j++)
			cout << num[j];
			return;	
		}
	}  
	for(int i = 0 ; i < 8 ; i++)
	{
		int tx = x + dx[i];
		int ty = y + dy[i];
		if(!vis[tx][ty] && tx >= 1 && tx <= n && ty >=1 && ty <= n && a[tx][ty] == cnt)
		{
			if(mp[dx[i]*8+dy[i]]== 1 || mp[dx[i]*8+dy[i]]== 3 || mp[dx[i]*8+dy[i]]== 5 || mp[dx[i]*8+dy[i]]== 7) //判断会出现斜线的情况 
			{
				if(check(x,y,dx[i],dy[i])) 
				continue; 
			}
			attached[x*10+y][tx*10+ty] = true;//二维转化为一维,对应是否建立连接 
			attached[tx*10+ty][x*10+y] = true;//二维转化为一维,对应是否建立连接 
			vis[tx][ty] = true;
			num.push_back(mp[dx[i]*8+dy[i]]);
			
			dfs(tx,ty,step+1,(cnt+1)%k);
			
			attached[x*10+y][tx*10+ty] = false;//二维转化为一维,对应是否建立连接 
			attached[tx*10+ty][x*10+y] = false;//二维转化为一维,对应是否建立连接 
			vis[tx][ty] = false;
			num.pop_back();
		}
	}

}
int main()
{
	cin >> n >> k;
	for(int i = 1 ; i <= n ; i++)
	{
		for(int j = 1 ; j <= n ; j++)
		{
			cin >> a[i][j];
		}
	}
	for(int i = 0 ; i < 8 ; i++)//作为一种映射方向 
	{
//		cout <<"dx[i]*dy[i] :" << dx[i]*8+dy[i] <<"----------------mp[dx[i]*8+dy[i]]] :" << 	mp[dx[i]*8+dy[i]] << endl;
		mp[dx[i]*8+dy[i]] = i;
	}
	vis[1][1] = true; 
	dfs(1,1,1,1);
	if(found)
	{

	}
	else
	cout << -1;
  	return 0;
}

相关文章:

  • JAVA 单调栈习题解析
  • 入剖析 Android Compose 框架的关键帧动画(keyframes、Animatable)(二十三)
  • 蓝耘云平台免费 Token 获取攻略:让创作成本直线下降 - 极致优化版
  • Maven 构建配置文件
  • 工作效率upup
  • Ubuntu20.04.6系统根目录扩容
  • JWT 鉴权常见知识点及参考答案
  • nginx代理前端请求
  • 试试智能体工作流,自动化搞定运维故障排查
  • 地平线AlphaDrive:首个基于GRPO的自动驾驶大模型,仅用20%数据,性能超越SFT 35%!
  • Spring Boot整合Spring Data JPA
  • 报错 standard_init_linux.go:228: exec user process caused: exec format error
  • epoll:Linux 高性能 I/O 多路复用技术
  • 【零基础入门unity游戏开发——unity3D篇】3D模型 —— Animation动画页签
  • 备份比赛数据【算法赛】
  • 深度学习 Deep Learning 第9章 卷积网络 CNN
  • SpringBoot3-整合WebSocket指南
  • PostgREST实现DBaaS(数据库即服务)
  • Python:多线程意义及应用场景
  • 【Git江湖秘典——禁制、心法与渡劫篇】
  • 怎样正确看待体脂率数据?或许并不需要太“执着”
  • 长和获准出售巴拿马运河港口以外的港口?外交部:该报道没有依据
  • 消费者在天猫一旗舰店换手机电池疑遭套路致手机损坏,平台已介入
  • 从陈毅杯到小应氏杯,五一长假上海掀起围棋热
  • 李学明谈笔墨返乡:既耕春圃,念兹乡土
  • 五一上海楼市热闹开局:售楼处全员到岗,热门楼盘连续触发积分