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

19712 数字接龙

 

/*我觉得重要的理解点:1.四维数组白表示一个点从另一个点沿对角线的方式进行移动,如果这个元素的值为真则表示这样的移动存在。 2.按照0->k-1的顺序移动。这个要求的实现方法也值得学习 3.count和index的含义: index表示索引,表示第index步。当index=0表示在起点,ndex=1表示从原点出发走了一步。count表示走过的格子数。count=n*n表示所有的格子都已经走过。
*/ 
#include<bits/stdc++.h>
using namespace std;
int n, k, fx[8][2] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}}; // 2列8行的数组,按照行初始化
//从向左移动开始。顺时针的移动顺序
//即正左,左上,正上,右上,正右,右下,正下,左下
int maps[11][11]; // 存储地图信息的二维数组
bool vis[11][11], b = false, check[11][11][11][11]; // 访问标记,结束标记,交叉检查
vector<int> v; // 存储路径
//四维数组check[a][b][c][d]表示从(a,b)->(c,d)其中此两点为对角线关系,
//即check[a][b][c][d]表示(a,b)通过斜线访问到(c,d);
//同样的check[c][d][a][b]表示从(c,d)->(a,b)// 深度优先搜索函数
void dfs(int x, int y, int index, int count) {if (b) return; // 剪枝,如果已经找到答案则不再继续搜索if (x == n && y == n && count == n * n) { // 判断是否到达终点//count表示走过的格子总数b = true;for (int i = 0; i < v.size(); i++) cout << v[i]; // 输出路径return;for (int i = 0; i < 8; i++) { // 遍历所有可能的移动方向int xx = x + fx[i][0], yy = y + fx[i][1]; // 新坐标if (xx < 1 || yy < 1 || xx > n || yy > n || vis[xx][yy]) continue; // 判断移动是否合法if (maps[xx][yy] != (index + 1) % k) continue; //index"索引". index=0表示在当前位置//index+1 表示下一个步骤的位置//maps[x][y]+1=maps[xx][yy]//[x][y]时index=index;//[xx][yy]index=index+1;//%k使得能够循环判断。将值控制在0->k-1的范围之内。//判断是否按照0~k-1的顺序走.if (i % 2 && check[x + fx[i][0]][y][x][y + fx[i][1]] || check[x][y + fx[i][1]][x + fx[i][0]][y]) continue; // 交叉检查//if触发条件:对角线移动且存在交叉//示意图:  a b//         c d//判断交叉的原理:假设从c(x,y)点出发,当i=3时表示向右上移动到b;//此时check[x + fx[i][0]][y][x][y + fx[i][1]]为check[x+1][y][x][y+1]//即a->d是否为1//同时判断check[x + fx[i][0]][y][x][y + fx[i][1]] (check[x][y+1][x+1][y])//即d->a是否为1//有一个为1则为交叉vis[xx][yy] = true; // 标记为已访问if (i % 2) {check[x][y][xx][yy] = true; check[xx][yy][x][y] = true;} // 标记交叉点v.push_back(i); // 答案的写入dfs(xx, yy, (index + 1) % k, count + 1); // 递归vis[xx][yy] = false; // 回溯//回溯的原因//1.没有按照规定的顺序走 0->k-1//2.存在交叉//3.越界或者到终点//回溯之后说明这个点非法,则将标记清除,不影响其他路径规划。if (i % 2) {check[x][y][xx][yy] = false; check[xx][yy][x][y] = false;} // 回溯交叉点v.pop_back(); }
}int main() {cin >> n >> k; // 输入网格大小和要求for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {cin >> maps[i][j]; // 输入网格信息}}vis[1][1] = true; // 从(1,1)开始dfs(1, 1, 0, 1); // 深度优先搜索if (!b) cout << -1; // 如果没有找到答案,输出-1return 0;
}

无向图存在欧拉回路(回到原点)的充要条件:每个点的度数为偶数

度数:连接一个点的条数。 为奇数的点为奇点,偶数为偶点。

不闭合的欧拉路径存在的充要条件:奇顶点的个数等于0或2;

定理2:一个无向图有2n个奇顶点,最少需要n笔画成;

一个图是否能够不重复的遍历所有顶点:能则为哈密顿图

哈密顿图:遍历所有顶点

欧拉:遍历所有边


http://www.mrgr.cn/news/82210.html

相关文章:

  • STM32的LED点亮教程:使用HAL库与Proteus仿真
  • ZYNQ初识7(zynq_7010)RAM_IP核
  • C++ 设计模式:备忘录模式(Memento Pattern)
  • 选择器(结构伪类选择器,伪元素选择器),PxCook软件,盒子模型
  • Unity 实现Canvas显示3D物体
  • 第十届“挑战杯”大学生课外学术科技作品竞赛解析及资料
  • TTL 传输中过期问题定位
  • FOC控制原理7-源码解析2-系统滴答定时器中断
  • 使用ebooklib制作符合epub3规范的epub文件
  • C++语言编程————C++数据类型
  • 解决virtualbox克隆ubuntu虚拟机之后IP重复的问题
  • java Redisson 实现限流每秒/分钟/小时限制N个
  • 【复刻】ESG表现对企业价值的影响机制研究(2009-2021年)
  • 一、VxLAN 简介
  • 旷视科技Java面试题及参考答案
  • NRF24L01模块通信实验
  • 日期时间选择(设置禁用状态)
  • linux系统安装搭建chrony(ntp)时间同步服务器
  • git使用指南-实践-搭建git私服
  • 数据仓库中的指标体系模型介绍
  • Frontend - 分页(针对 python / Django )
  • 用Python操作字节流中的Excel工作簿
  • SpringCloud源码分析-Ribbon与LoadBalancer
  • python实现自动登录12306抢票 -- selenium
  • Yolo11改进策略:注意力改进|Neck层改进|SCSA,探索空间与通道注意力之间的协同效应|即插即用
  • 【Rust自学】9.2. Result枚举与可恢复的错误 Pt.1:match、expect和unwrap处理错误