前排提示,本文收录的题目不是全部,只是抽取一些题目进行解析。因为笔者是在写完所有题之后在写此篇,推导过程中的量的名称可能与参考代码中不一样,还望谅解。

题目链接:信息学奥赛一本通(C++版)在线评测系统

1212:LETTERS

【题目描述】

给出一个roe×col的大写字母矩阵,一开始的位置为左上角,你可以向上下左右四个方向移动,并且不能移向曾经经过的字母。问最多可以经过几个字母。

【输入】

第一行,输入字母矩阵行数R和列数S,1≤R,S≤20。

接着输出R行S列字母矩阵。

【输出】

最多能走过的不同字母的个数。

【输入样例】

3 6
HFDFFB
AJHGDH
DGAGEH

【输出样例】

6

【推导过程】

每次从一个点出发,可以向右与向下走,不能走回头路,使用vis_le[]记录已经走过的路;同时也不能走已经走过的字母,采用一个桶数组vit_[]标记走过的数组;为了记录偏移量,定义dr[]{-1,0,1,0}与dc[]{0,-1,0,1}(绕一圈的量)记录偏移量,使用循环。之后再采用搜索与回溯算法,查找可以走的路并储存。

【参考代码】

# include<iostream>

# include<cstring>

using namespace std;

const int maxn=26;

int r,s;

int g[maxn][maxn];

string ss;

int Max;

bool vis_le[maxn];  //标记字母

bool vis_[maxn][maxn];//标记点

int dr[]={1,0,-1,0};

int dc[]={0,-1,0,1};

void search(int x,int y,int step)

{

if(step>Max)

Max=step;

for(int i=0;i<4;i++)

{

int newx=x+dr[i];

int newy=y+dc[i];

if(newx>=0&&newx<r&&newy>=0&&newy<s&&!vis_le[g[newx][newy]]&&!vis_[newx][newy])

{

vis_le[g[newx][newy]]=vis_[newx][newy]=1;

search(newx,newy,step+1);

vis_le[g[newx][newy]]=vis_[newx][newy]=0;

}

}

}

int main()

{

cin>>r>>s;

for(int i=0;i<r;i++)

{

cin>>ss;

for(int j=0;j<ss.size();j++)

{

g[i][j]=ss[j]-'A';

}

}

memset(vis_le,0,sizeof(vis_le));

memset(vis_,0,sizeof(vis_));

vis_le[g[0][0]]=1;vis_[0][0]=1;  //站在第一个点去向四周做选择,并把第一个点死锁

search(0,0,1);   //因为第一个点有一个字母,故已访问一个字母,所以第三个参数为1

cout<<Max<<endl;

return 0;

}

1213:八皇后问题

【题目描述】

在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方。

【输入】

(无)

【输出】

按给定顺序和格式输出所有八皇后问题的解(见样例)。

【输入样例】

(无)

【输出样例】

No. 1
1 0 0 0 0 0 0 0 
0 0 0 0 0 0 1 0 
0 0 0 0 1 0 0 0 
0 0 0 0 0 0 0 1 
0 1 0 0 0 0 0 0 
0 0 0 1 0 0 0 0 
0 0 0 0 0 1 0 0 
0 0 1 0 0 0 0 0 
No. 2
1 0 0 0 0 0 0 0 
0 0 0 0 0 0 1 0 
0 0 0 1 0 0 0 0 
0 0 0 0 0 1 0 0 
0 0 0 0 0 0 0 1 
0 1 0 0 0 0 0 0 
0 0 0 0 1 0 0 0 
0 0 1 0 0 0 0 0 
...以下省略

【推导过程】

这是一道很经典的题目。算法的基本思路是依次在每一列的每一个点(列数不与上一个重合),并查看是否符合要求,不符合递归摆放下一个(行数加1,到达边界后行数重置,列数加1),符合记录坐标,定义a[],表示第i行的皇后在第j列。录8个摆放完毕后输出答案。皇后可以吃同一行——摆放是行数加1、同一列——建立b[],=1表示第j列有皇后了,=0就便是没有、同一对角线的棋子——先建立ysx[],表示从左下到右下的对角线,总共15条斜线,每条斜线上所有格子 行号+列号=固定值,值范围2至16;再建立yxx[],表示从左上到右下的对角线,总共15条斜线,每条斜线上所有格子 行号-列号=固定值 ,值范围7至-7(C++不能操控负数组,所以[14]并+7)。

【参考代码】

#include<iostream>

using namespace std;

int a[9];//a[i]=j 记录第i行的皇后在j列

int b[9];//b[j]=1 表示第j列有皇后了,=0表示第j列没有皇后

int qipan[9][9];//记录棋盘中的数字,有皇后的格子数字为1,没有皇后的格子为0

int ysx[16];//表示从左下到右上的斜线,y=右,s=上,x=斜,总共15条斜线,每条斜线上所有格子 行号+列号=固定值,值范围2至16,

int yxx[16];//表示从左上到右下的斜线,y=右,x=下,x=斜,总共15条斜线,每条斜线上所有格子 行号-列号=固定值 ,值范围7至-7

int i,j,sum;//sum记录多少种可能

void print();

void dfs(int i) //确定第i行皇后位置

{

int j;

for(j=1;j<=8;j++)

{

if(b[j]==0&&ysx[i+j]==0&&yxx[i-j+7]==0)//1.这一列没有皇后,2.这个点并不在某个皇后覆盖的从左下到右上的斜线上,3. 这个点并不在某个皇后覆盖的从左上到右下的斜线上

{

a[i]=j;

b[j]=1;

qipan[i][j]=1;

ysx[i+j]=1;

yxx[i-j+7]=1;

if(i==8)

{

//if(sum<3)

print();

}

else

dfs(i+1);

//以下为回溯

a[i]=0;

b[j]=0;

qipan[i][j]=0;

ysx[i+j]=0;

yxx[i-j+7]=0;

}

}

return;

}

void print()

{

sum++;

int m,n;

cout<<"No. "<<sum<<endl;

for(m=1;m<=8;m++)

{

for(n=1;n<=8;n++)

{

if(qipan[n][m]==1)

cout<<"1"<<" ";

else

cout<<"0"<<" ";

}

cout<<endl;

}

return;

}

int main()

{

dfs(1);

return 0;

}

1214:八皇后

【题目描述】

会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 × 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。

对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。

给出一个数b,要求输出第b个串。串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小。

【输入】

第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数b(1≤b≤92)。

【输出】

输出有n行,每行输出对应一个输入。输出应是一个正整数,是对应于b的皇后串。

【输入样例】

2
1
92

【输出样例】

15863724
84136275a

【推导过程】

只是在判断处、输出处不同,与之前的是一样的

【参考代码】

#include<bits/stdc++.h>

using namespace std;

int a[8][8],ab=0;

int b[1000];

int c[1000];

int n,a1;

bool cheak(int x,int l)

{

for(int i=x;i>=0;i--)

{

if(a[i][l]==1)

{

return 0;

}

}

for(int k=x,c=l;k>=0&&c>=0;k--,c--)

{

if(a[k][c]==1)

{

return 0;

}

}

for(int k=x,c=l;k>=0&&c<8;k--,c++)

{

if(a[k][c]==1)

{

return 0;

}

}

return 1;

}

void fun(int x)

{

int l;

if(x>7)

{

ab++;

if(ab==a1)

{

for(int i=0;i<8;i++)

{

cout<<b[i]+1;

}

cout<<endl;

}

}

else

{

for(l=0;l<8;l++)

{

if(cheak(x,l))

{

a[x][l]=1;

b[x]=l;

fun(x+1);

a[x][l]=0;

}

}

}

}

int main()

{

int a;

cin>>n;

for(int i=0;i<n;i++)

{

cin>>a1;

fun(0);

ab=0;

}

return 0;

}

1215:迷宫

【题目描述】

一天Extense在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由n×n的格点组成,每个格点只有2种状态,.#,前者表示可以通行后者表示不能通行。同时当Extense处在某个格点时,他只能移动到东南西北(或者说上下左右)四个方向之一的相邻格点上,Extense想要从点A走到点B,问在不走出迷宫的情况下能不能办到。如果起点或者终点有一个不能通行(为#),则看成无法办到。

【输入】

第1行是测试数据的组数kk,后面跟着kk组输入。每组测试数据的第11行是一个正整数n(1≤n≤100),表示迷宫的规模是n×n的。接下来是一个n×n的矩阵,矩阵中的元素为.或者#。再接下来一行是4个整数ha,la,hb,lb,描述A处在第ha行, 第la列,B处在第hb行, 第lb列。注意到ha,la,hb,lb全部是从0开始计数的。

【输出】

k行,每行输出对应一个输入。能办到则输出“YES”,否则输出“NO”。

【输入样例】

2
3
.##
..#
#..
0 0 2 2
5
.....
###.#
..#..
###..
...#.
0 0 4 0

【输出样例】

YES
NO

【推导过程】

首先,这道题只需要搜索而不需要回溯,这道题只需要查找到终点,能就输出”YES”,不能就输出”NO”,不需要记录。为了使“可以走”与“不能走”形成“true”与“false”,定义ch(char型),先读入ch,判断后存入a[][](0与1的形式)。与其它偏移题一样,定义偏移量数组dx[]{-1,0,1,0}与dy[]{0,-1,0,1}。在输入完数据后,需要进行特判,如果起点或终点就是障碍物,直接输入”NO”; 之后定义标志变量flag,初始化为false。为了防止不走回头路,需要一个标识数组b[][]。没越界、没有障碍物、没走过满足3者才可以走,否则直接失败;如果成功,flag=true。

最后判断——flag=false输出”NO”,flag=true输出“Yes“。(记得用循环!!!)

【参考代码】

#include<bits/stdc++.h>

using namespace std;

int k, n;

char a[105][105]; //地图

int b[105][105]; //标记数组

int d[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; //方向数组

int startx, starty, endx, endy;

bool flag;

void dfs(int x, int y) {

//递归出口

if (x == endx && y == endy) {

cout << "YES" << endl;

flag = true;

return;

}

//递归条件

for (int i = 0; i < 4; i++) {

int nextx = x + d[i][0];

int nexty = y + d[i][1];

if (nextx >= 0 && nexty >= 0 && nextx < n && nexty < n && a[nextx][nexty] == '.' && !b[nextx][nexty]) {

//没越界、没有障碍物、没走过,同时满足三者才可以走

b[nextx][nexty] = 1;

dfs(nextx, nexty);

//b[nextx][nexty] = 0;

}

}

}

int main()

{

cin >> k;

for (int i = 0; i < k; i++) {

//初始化工作

memset(a, 0, sizeof(a));

memset(b, 0, sizeof(b));

//输入地图维度

cin >> n;

//输入地图

for (int row = 0; row < n; row++) {

for (int col = 0; col < n; col++) {

cin >> a[row][col];

}

}

//输入起点终点

cin >> startx >> starty >> endx >> endy;

//特判

if (a[startx][starty] == '#' || a[endx][endy] == '#') { //起点或终点为#

cout << "NO" << endl;

continue;

}

flag = false;

b[startx][starty] = 1;

dfs(startx, starty);

if (flag == false) cout << "NO" << endl;

}

return 0;

}

搜索与回溯典型题目解析相关推荐

  1. Java实现搜索回溯经典题目

    文章目录 前言 搜索框架 经典问题 前言 搜索与回溯是计算机解题中常用的算法,很多问题无法根据某种确定的计算法则来求解,可以利用搜索与回溯的技术求解.回溯是搜索算法中的一种控制策略.它的基本思想是:为 ...

  2. Leetcode中二叉树中的搜索相关题目解析以及java实现

    Leetcode中二叉树中的搜索相关题目解析以及java实现 这一类的题目其实稍微有一些杂,基本就是在二叉树中寻找一些或者某个特定值,题目比较多,我们会通过两道三篇来总结,不过总体来说也基本上就是BF ...

  3. Mysql窗口函数 (知识点梳理+题目解析+面试实战)(四万字长文,一文读懂,建议收藏后食用)

    前言: 本文章是原创50篇时开启的纪念作,之前的文章基本5000字,而本篇约4.5万字,真一篇顶九篇. 窗口函数作为Mysql 8的新特性以及面试笔试的重点,掌握并且进行来练习是非常有必要的.本文章详 ...

  4. 2022春秋杯联赛 传说殿堂赛道 sql_debug题目解析

    2022春秋杯联赛 传说殿堂赛道 sql_debug题目解析 前言 sql_debug sql_debug 题⽬介绍 dsn_from_uri 触发phar反序列化 Linux下PHP内核调试⼩知识 ...

  5. 搜索与回溯 1215:迷宫

    [题目描述] 一天Extense在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由n * n的格点组成,每个格点只有2种状态,.和#,前者表示可以通行后者表示不能通行.同时当Extense处在某 ...

  6. 【搜索与回溯算法】保卫农场(DFS)

    [搜索与回溯算法]保卫农场 (Standard IO) 时间限制: 1000 ms  空间限制: 262144 KB  具体限制 题目描述: 农夫John的农场里有很多小山丘,他想要在那里布置一些保镖 ...

  7. Nuist集训队作业:深度优先搜索(回溯算法)

    Nuist集训队第一次作业:深度优先搜索(回溯算法) 引例 深搜基本思想及回溯算法模板 P1706 全排列问题 P1219 八皇后 P1605 迷宫 P1101 单词方阵 小结 引例 国际西洋棋棋手马 ...

  8. 计算机网络-关于IP地址与子网划分的题目解析

    知识笔记 关于子网号全0全1问题: 现在子网号全0全1是可用的,但09年之前因为协议原因不可用全0全1划分子网.根据考研要求可知已经部分高校认定全0全1可以使用,个人认为不确定时以可以用全0全1划分子 ...

  9. 2015年第六届蓝桥杯C/C++B组省赛题目解析

    1.奖券数目 有些人很迷信数字,比如带"4"的数字,认为和"死"谐音,就觉得不吉利. 虽然这些说法纯属无稽之谈,但有时还要迎合大众的需求.某抽奖活动的奖券号码是 ...

最新文章

  1. 昆仑通态通用版找不到驱动_2021深圳新安西门子伺服驱动电机回收合作共赢
  2. jQuery/javascript实现简单网页计算器
  3. LFTP : 一个功能强大的命令行FTP程序
  4. CVPR2019| 最新CVPR2019论文:含目标检测、分割、深度学习、GAN等领域
  5. python log模块_Python日志模块-logging
  6. 一个很好的开源图像处理软件--imageJ (2
  7. BEGINNING SHAREPOINT#174; 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 client对象模型(CSOM)基础...
  8. pyqt5 yolov4实现车牌识别系统
  9. 关于WiFi密码破解的一些心得
  10. C#之Dispose
  11. 精通 Spring Boot 42 讲
  12. Chrome设置--disable-web-security解决跨域问题
  13. “剧情+综艺” 助推国潮文化破圈
  14. 两种图像骨架提取算法的研究原理及实现
  15. 几种比较好看的颜色代码
  16. 微信朋友圈附近推效果怎么样?
  17. 人脸识别中的全脸/半脸/中脸
  18. XSS与字符编码的那些事儿
  19. 25. Green Living 绿色生活
  20. android锁屏时间大小,Android 4.4.4 锁屏界面时间大小修改

热门文章

  1. 防火墙和NAT基础学习
  2. 企业内部即时通讯工具支持内网私有化部署
  3. matlab画y x 2,matlab怎么绘制z=sqrt(x^2 y^2)的图像
  4. (转)PC+运动控制卡的控制方案
  5. 菜鸟之路---2,简单的勒索病毒分析
  6. HTTP/2.0 中英文对照
  7. [Python练习-文件] 多目录下的字幕vtt转srt
  8. java timewait_time_wait和close_wait产生原因及解决
  9. Eureka注册发现及Feign调用示例
  10. Google大数据三大论文-MapReduce--中文翻译