2021.6.7.
今天主要复习了不太熟的深度优先搜索
1.1博客学习
其实DFS就像走迷宫一样,当我们走到某个分岔口,由于不知道到底哪个是出口,所以我们只能随便选择一条路(编程时一般是按顺序从第一个开始遍历),当我们又碰到一个分岔口时,我们需要再进行选择,如果碰到死胡同,这时就需要我们原路返回到上一个分岔口,然后选择另一条路,如此往复,直到走出迷宫。
————————————————
版权声明:本文为CSDN博主「Ays_Freeer」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/LPL_hacker/article/details/76019856
1.2总结一下主要的知识点和相关内容
1.2.1关于深搜合“法”的定义如下
(1).必须在所给定的范围内
(2).这个点在本次搜索中没有访问过(也就是说,一个点在dfs的时候只能被访问一次,不能重复访问,因为如果访问过,就容易出现死循环)
1.2.2深搜通常写成递归的形式
还有很多,就不在这里一一呈现了,
今天差不多了,明天再巩固一下深度优先搜索
PS.今天高考首日,祝各位学长学姐们,高考加油,旗开得胜~
2021.6.8.
今天完成了洛谷P1029和P1618(作为热身)
这两道题不算很难,就是写起来比较费时间
下面切入今天的正题:
2.1复习八皇后
2.1.1先复习一下八皇后的规则
八皇后问题,是由国际西洋棋棋手马克斯·贝瑟尔于1848年提出的问题,是回溯算法的典型案例。
问题表述为:在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。如果经过±90度、±180度旋转,和对角线对称变换的摆法看成一类,共有42类。计算机发明后,有多种计算机语言可以编程解决此问题
声明:本文来自百度百科
2.1.2下面来看看具体的解法(来自洛谷P1219题解)
对于八皇后问题我们可以把它转化为精确覆盖的问题:
- 每行只能放一个皇后
- 每列只能放一个皇后
- 每一个“/”斜行只能放一个皇后
- 每一个“\”斜行只能放一个皇后
我们把每个状态当成列,每个点当成一行 然后精确覆盖这个矩阵
注意:与模版不同的是我们只需保证每行每列完全覆盖而每一斜行是肯定不能完全覆盖的(因为一共2*n-1个斜行)
2.1.3最后把代码写两遍吧
<我的代码参照老师上课讲的代码完成>
# include <iostream>
# include <string.h>
# include <stdio.h>
# include <stdlib.h>
# include <algorithm>
using namespace std;
bool a[30] , b[30] , c[30] ;
int n , sum , d[30];
void print()
{
for (int i= 1;i<= n;i++) printf("%d " , d[i]) ;
printf("\n") ;
sum ++ ;
}
void find (int i)
{
if (i>n) if (sum<3) print() ; else sum ++ ;
else {
for (int j= 1;j<= n;j++)
{
if (a[j] and b[i+j] and c[i-j+n]) {
a[j] = b[i+j] = c[i-j+n] = 0 ;
d[i] = j ;
find(i+1 ) ;
a[j] = b[i+j] = c[i-j+n] = 1 ;
}
}
}
}
int main() {
cin>>n ;
memset(a, 1 ,sizeof(a)) ;
memset(b, 1 ,sizeof(b)) ;
memset(c, 1 ,sizeof(c)) ;
find(1) ;
printf("%d\n", sum) ;
return 0;
}
其实八皇后主要核心就是回溯算法
再做两道题巩固一下深搜(之前做过,现在再复习写一遍)P2392和P1443
今天就先到这里了
2021.6.9.
1.1今天一直在学文化课,晚上才发现还没做题呢,那今天就做两道,P5707和P3954(我今天才发现第一个题单还有没做完的题目)
2021.6.10
今天复习广搜
1.1先来博客学习一下
首先访问初始点v并将其标志为已经访问。接着通过邻接关系将邻接点入队。然后每访问过一个顶点则出队。按照顺序,访问每一个顶点的所有未被访问过的顶点直到所有的顶点均被访问过。
广度优先遍历类似与层次遍历。其特点是尽可能先对横向进行搜索,从指的出发点,按照该点的路径长度由短到长的顺序访问图中各顶点。
利用队列先进先出的性质,从起点开始,将一步能到达的点全部存入队列,然后将队列中队首元素出队,执行与起点相同的操作,以此循环,直到到达终点或者队列为空,队列为空说明可以到达的点都已经遍历过了,也就是说没有路可以到达终点。
————————————————
版权声明:本文为CSDN博主「acm小新笙」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/acm147258369/article/details/88562558
1.2各处搜寻资料总结一下<我的笔记>
(这张图里面有一个很巧妙的理解方法)
今天没时间了,明天再刷题
PS.今天高考结束,我们明天也要返校了,调整好状态,准备期末冲刺!
2021.6.11.
今天主要做了几道洛谷上的题目
虽然有一些之前做过,但是是老师带着做的,自己又做一遍还是调了很久的
做了P1135P1443P1101P2404
明天在学习新的吧
周末愉快!
2021.6.12.
今天复习一下排序(其他排序还好,主要复习桶排、堆排、二分排序和希尔排序)
在这里分享一下希尔排序的程序(也是我第一次打问题比较大的一个程序)
#include <bits/stdc++.h>
using namespace std;
const int N=1e7+6;
int a[N];
int main(){
srand (time(0));
int n=100000;
for(int i=1;i<=n;i++) a[i]=rand()%100000;
int d=n/2;
while (d>0){
for(int i=d;i<=n;i++){
int j=i-d;
while (j>0&&a[j]>a[j+d]) swap(a[j],a[j+d]),j-=d;
}
d/=2;
}
for(int i=1;i<=n;i++) cout<<a[i]<<" ";
cout<<endl;
return 0;
}
这是二分排序的主程序
今天就先到这里啦
2021.6.13.
今天要准备期末复习,就先不学新的了(明天端午节放假,再学点新的吧-具体见下周日报)
今天先打了一遍迪杰斯特拉算法
然后又打了一遍希尔排序,竟然一遍过,开心:)
本周总结
这周主要是复习不熟悉的算法,反复练习才能熟能生巧,这周主要是因为高考放假所以多刷了一些题,希望下周“忙起来”了每天也可以练练
继续加油!