1.求细胞数量
这道题主要是搜索0与其他数字之间的间隔,可以写一个深搜,如果搜到0就返回,如果是1-9就继续搜索,读入需要使用二维数组,将每个点都遍历,只要没有标记过并且不是0的点就进行搜索,之后输出总值即可
x1 =[1,-1,0,0]
y1 =[0,0,1,-1]
n,m = map(int,input().split())
visit = [[0 for i in range(m+1)]for row in range(n+1)]
flag = [[0 for i in range(m+1)]for row in range(n+1)]
for i in range(n): #进行输入
temp = input()
for j in range(m):
visit[i][j] =temp[j]
def dfs(x, y): # 使用dfs进行
global flag
if(x<0 or x>=n or y<0 or y>=m):
return
if (visit[x][y] == '0' or flag[x][y]):
return
flag[x][y] = 1
for i in range(4):
dfs(x+x1[i],y+y1[i]) #进行遍历
sumvalue=0 #
for i in range(n): #进行输入
for j in range(m):
if(visit[i][j]!='0' and (not flag[i][j])): #如果不是0并且没有被标记
dfs(i,j) #进行遍历
sumvalue+=1
print(sumvalue)
2.组合的输出
对于这一题,主要是从1开始搜索,首先在数组中加入一个0可以访问-1,然后从小到大依次加入列表,判断是否达到了r长度,输出时使用%3d进行输出
code:
n,r = map(int,input().split()) #
def dfs(list1):
if(len(list1)==r+1):
for i in range(1,r+1):
print("%3d"%(list1[i]),end='')
print()
return
for i in range(list1[-1]+1,n+1):
list1.append(i)
dfs(list1)
list1.pop()
a=[0]
dfs(a)
3.好奇怪的游戏
参考leetcode:leetcode-cn.com/problems/fl…
这样的搜索需要使用两种,这种的主要用广搜来做,因为是要求最小的步数,一层一层的进行,首先将初始条件进行put(),然后遍历所有方案之后进行put操作,依次执行后,找到第一个到达的就是最短路程.bfs与dfs的差别就是一个是在同层遍历,一个是在深层次遍历:
from queue import Queue
for i in range(2):
endx,endy =map(int,input().split())
que = Queue() #也就是使用Queue数据结构进行
visit = [[0 for i in range(200)]for row in range(200)] #得到了visit的矩阵
dx=[1,1,2,2,2,2,-1,-1,-2,-2,-2,-2]
dy=[-2,2,-2,-1,1,2,-2,2,-1,1,-2,2]
def bfs():
que.put((1,1,0))
while not que.empty():
tempx,tempy,step = que.get()
for i in range(12):
x,y= tempx+dx[i],tempy+dy[i]
if(x<0 or y<0 or x>=100 or y>=100 or visit[x][y]):
continue
visit[x][y] = 1
if((y==endy) and (x==endx)):
return step+1
que.put((x,y,step+1)) #得到下一步的位置进入队列
step = bfs()
print(step)
while not que.empty(): #消除队列中元素
que.get()
4.血色先锋队
这一题主要是由多个传染源的话,只需要在一开始就把他们全部压入队列就行,之后再压出来进行bfs,
Code
from queue import Queue
dx =[1,-1,0,0]
dy =[0,0,1,-1]
n,m,a,b = map(int,input().split())
map1 = [[0 for i in range(m+1000)]for row in range(n+1000)]
queue = Queue(maxsize = 100000) #Queue用来进行bfs.
def bfs():
global map1 #也就是使用map
while not queue.empty():
tempx,tempy,step = queue.get()#得到每个点的信息
for i in range(4):
x,y = tempx+dx[i],tempy+dy[i]
if(x>n+1 or x<0 or y<0 or y>m+1 or map1[x][y]): #如果这个东西很大了就必须扔掉
continue
map1[x][y] = step+1 #将这个step纪录下来
queue.put((x,y,step+1)) #将x,y放入队列,并且放入step
for i in range(a): #
x,y = map(int,input().split())
queue.put((x,y,0)) #也就是从0开始感染的话
map1[x][y] = 10000
bfs()
for i in range(b):
x,y = map(int,input().split()) #
if(map1[x][y]==10000):
print(0) #map1到底有多少
else:
print(map1[x][y])
5.数的划分
这个题主要是用搜索,构建一个函数纪录当前的遍历的数位置和使用的数的个数,当使用的数的个数等于k时,就判断与原来的数相等,相等就使方案加1,代码较简单
6.迷宫
www.luogu.com.cn/problem/P11…
这道题不同于其他的题目在于连通块的判断,首先我是用了一个递归进行赋值,但是出错的地方就在于不同方向的节点不相等,导致了WA,
关于深度优先搜索:
深度优先搜索写代码有两种,一种将判断条件写在最上层:
def dfs(value):
if(seen[value]): #如果已经访问过了 返回
return
seen[value]=True
answer.append(value)
for i in list1[value]: #在列表中
dfs(i)
如果只有一个起点开始的,可以将判断条件放在里面,但是使用上面那种更加通用
def dfs(value): #
seen[value]=True
answer.append(value)
for i in list1[value]: #在列表中
if(not seen[i]): #如果已经访问过了 返回
dfs(i)
关于广度优先搜索:
广度优先搜索都是用队列来写:
C语言的写完是这样的
void bfs(int x){ //bfs——广度优先遍历(x依然是第几号顶点,不过既然不递归其实传这个参数也没啥用)
queue <int> q; //没有队列那还叫广搜吗
q.push(x); //先把第一个顶点推进去,输出,标记访问过
cout<<x<<" ";
vis2[x]=1;
while(!q.empty()){ //广搜板子,上!
int fro=q.front(); //把队首取出来
for(int i=0;i<e[fro].size();i++){ //每条边去试
int point=s[e[fro][i]].v; //取终点(和dfs差不多)
if(!vis2[point]){ //没访问过,推进去,输出,标记
q.push(point);
cout<<point<<" ";
vis2[point]=1;
}
}
q.pop(); //队首搜完啦!把它弄出去
}
}
队列的作用就是将一个层次的节点给存入,先进先出的特点符合广度优先搜索的特点.
关于二叉树
二叉树的题目有关于很多都是关于排名的游戏,如果是遇到这种需要找到第一名是谁,第二名是谁的题目,可以使用队列来做,因为比赛总是从两个人中选择强的,也就是pop两个而push一个.
from queue import Queue
queue = Queue()
n = int(input())
m = list(map(int,input().split())) #输入数组
for i in range(len(m)):
queue.put((m[i],i+1)) #第i位选手
while(queue.qsize()>2): #如果只有两个
x = queue.get()
y = queue.get()
if(x[0]>=y[0]):
queue.put(x)
else:
queue.put(y)
x = queue.get()
y = queue.get()
if(x[0]>y[0]): #如果x[0]
print(y[1])
else:
print(x[1]) #为什么是滴
#### 5.数的划分
这个题主要是用搜索,构建一个函数纪录当前的遍历的数位置和使用的数的个数,当使用的数的个数等于k时,就判断与原来的数相等,相等就使方案加1,代码较简单
6.迷宫
www.luogu.com.cn/problem/P11…
这道题不同于其他的题目在于连通块的判断,首先我是用了一个递归进行赋值,但是出错的地方就在于不同方向的节点不相等,导致了WA,
关于深度优先搜索:
深度优先搜索写代码有两种,一种将判断条件写在最上层:
def dfs(value):
if(seen[value]): #如果已经访问过了 返回
return
seen[value]=True
answer.append(value)
for i in list1[value]: #在列表中
dfs(i)
如果只有一个起点开始的,可以将判断条件放在里面,但是使用上面那种更加通用
def dfs(value): #
seen[value]=True
answer.append(value)
for i in list1[value]: #在列表中
if(not seen[i]): #如果已经访问过了 返回
dfs(i)
关于广度优先搜索:
广度优先搜索都是用队列来写:
C语言的写完是这样的
void bfs(int x){ //bfs——广度优先遍历(x依然是第几号顶点,不过既然不递归其实传这个参数也没啥用)
queue <int> q; //没有队列那还叫广搜吗
q.push(x); //先把第一个顶点推进去,输出,标记访问过
cout<<x<<" ";
vis2[x]=1;
while(!q.empty()){ //广搜板子,上!
int fro=q.front(); //把队首取出来
for(int i=0;i<e[fro].size();i++){ //每条边去试
int point=s[e[fro][i]].v; //取终点(和dfs差不多)
if(!vis2[point]){ //没访问过,推进去,输出,标记
q.push(point);
cout<<point<<" ";
vis2[point]=1;
}
}
q.pop(); //队首搜完啦!把它弄出去
}
}
队列的作用就是将一个层次的节点给存入,先进先出的特点符合广度优先搜索的特点.
关于二叉树
二叉树的题目有关于很多都是关于排名的游戏,如果是遇到这种需要找到第一名是谁,第二名是谁的题目,可以使用队列来做,因为比赛总是从两个人中选择强的,也就是pop两个而push一个.
from queue import Queue
queue = Queue()
n = int(input())
m = list(map(int,input().split())) #输入数组
for i in range(len(m)):
queue.put((m[i],i+1)) #第i位选手
while(queue.qsize()>2): #如果只有两个
x = queue.get()
y = queue.get()
if(x[0]>=y[0]):
queue.put(x)
else:
queue.put(y)
x = queue.get()
y = queue.get()
if(x[0]>y[0]): #如果x[0]
print(y[1])
else:
print(x[1]) #为什么是滴
#### 5.数的划分
这个题主要是用搜索,构建一个函数纪录当前的遍历的数位置和使用的数的个数,当使用的数的个数等于k时,就判断与原来的数相等,相等就使方案加1,代码较简单
6.迷宫
www.luogu.com.cn/problem/P11…
这道题不同于其他的题目在于连通块的判断,首先我是用了一个递归进行赋值,但是出错的地方就在于不同方向的节点不相等,导致了WA,
关于深度优先搜索:
深度优先搜索写代码有两种,一种将判断条件写在最上层:
def dfs(value):
if(seen[value]): #如果已经访问过了 返回
return
seen[value]=True
answer.append(value)
for i in list1[value]: #在列表中
dfs(i)
如果只有一个起点开始的,可以将判断条件放在里面,但是使用上面那种更加通用
def dfs(value): #
seen[value]=True
answer.append(value)
for i in list1[value]: #在列表中
if(not seen[i]): #如果已经访问过了 返回
dfs(i)
关于广度优先搜索:
广度优先搜索都是用队列来写:
C语言的写完是这样的
void bfs(int x){ //bfs——广度优先遍历(x依然是第几号顶点,不过既然不递归其实传这个参数也没啥用)
queue <int> q; //没有队列那还叫广搜吗
q.push(x); //先把第一个顶点推进去,输出,标记访问过
cout<<x<<" ";
vis2[x]=1;
while(!q.empty()){ //广搜板子,上!
int fro=q.front(); //把队首取出来
for(int i=0;i<e[fro].size();i++){ //每条边去试
int point=s[e[fro][i]].v; //取终点(和dfs差不多)
if(!vis2[point]){ //没访问过,推进去,输出,标记
q.push(point);
cout<<point<<" ";
vis2[point]=1;
}
}
q.pop(); //队首搜完啦!把它弄出去
}
}
队列的作用就是将一个层次的节点给存入,先进先出的特点符合广度优先搜索的特点.
关于二叉树
二叉树的题目有关于很多都是关于排名的游戏,如果是遇到这种需要找到第一名是谁,第二名是谁的题目,可以使用队列来做,因为比赛总是从两个人中选择强的,也就是pop两个而push一个.
from queue import Queue
queue = Queue()
n = int(input())
m = list(map(int,input().split())) #输入数组
for i in range(len(m)):
queue.put((m[i],i+1)) #第i位选手
while(queue.qsize()>2): #如果只有两个
x = queue.get()
y = queue.get()
if(x[0]>=y[0]):
queue.put(x)
else:
queue.put(y)
x = queue.get()
y = queue.get()
if(x[0]>y[0]): #如果x[0]
print(y[1])
else:
print(x[1]) #为什么是滴
5.数的划分
这个题主要是用搜索,构建一个函数纪录当前的遍历的数位置和使用的数的个数,当使用的数的个数等于k时,就判断与原来的数相等,相等就使方案加1,代码较简单
6.迷宫
www.luogu.com.cn/problem/P11…
这道题不同于其他的题目在于连通块的判断,首先我是用了一个递归进行赋值,但是出错的地方就在于不同方向的节点不相等,导致了WA,
关于深度优先搜索:
深度优先搜索写代码有两种,一种将判断条件写在最上层:
def dfs(value):
if(seen[value]): #如果已经访问过了 返回
return
seen[value]=True
answer.append(value)
for i in list1[value]: #在列表中
dfs(i)
如果只有一个起点开始的,可以将判断条件放在里面,但是使用上面那种更加通用
def dfs(value): #
seen[value]=True
answer.append(value)
for i in list1[value]: #在列表中
if(not seen[i]): #如果已经访问过了 返回
dfs(i)
关于广度优先搜索:
广度优先搜索都是用队列来写:
C语言的写完是这样的
void bfs(int x){ //bfs——广度优先遍历(x依然是第几号顶点,不过既然不递归其实传这个参数也没啥用)
queue <int> q; //没有队列那还叫广搜吗
q.push(x); //先把第一个顶点推进去,输出,标记访问过
cout<<x<<" ";
vis2[x]=1;
while(!q.empty()){ //广搜板子,上!
int fro=q.front(); //把队首取出来
for(int i=0;i<e[fro].size();i++){ //每条边去试
int point=s[e[fro][i]].v; //取终点(和dfs差不多)
if(!vis2[point]){ //没访问过,推进去,输出,标记
q.push(point);
cout<<point<<" ";
vis2[point]=1;
}
}
q.pop(); //队首搜完啦!把它弄出去
}
}
队列的作用就是将一个层次的节点给存入,先进先出的特点符合广度优先搜索的特点.
关于二叉树
二叉树的题目有关于很多都是关于排名的游戏,如果是遇到这种需要找到第一名是谁,第二名是谁的题目,可以使用队列来做,因为比赛总是从两个人中选择强的,也就是pop两个而push一个.
from queue import Queue
queue = Queue()
n = int(input())
m = list(map(int,input().split())) #输入数组
for i in range(len(m)):
queue.put((m[i],i+1)) #第i位选手
while(queue.qsize()>2): #如果只有两个
x = queue.get()
y = queue.get()
if(x[0]>=y[0]):
queue.put(x)
else:
queue.put(y)
x = queue.get()
y = queue.get()
if(x[0]>y[0]): #如果x[0]
print(y[1])
else:
print(x[1]) #为什么是滴
6.迷宫
www.luogu.com.cn/problem/P11…
这道题不同于其他的题目在于连通块的判断,首先我是用了一个递归进行赋值,但是出错的地方就在于不同方向的节点不相等,导致了WA,
关于深度优先搜索:
深度优先搜索写代码有两种,一种将判断条件写在最上层:
def dfs(value):
if(seen[value]): #如果已经访问过了 返回
return
seen[value]=True
answer.append(value)
for i in list1[value]: #在列表中
dfs(i)
如果只有一个起点开始的,可以将判断条件放在里面,但是使用上面那种更加通用
def dfs(value): #
seen[value]=True
answer.append(value)
for i in list1[value]: #在列表中
if(not seen[i]): #如果已经访问过了 返回
dfs(i)
关于广度优先搜索:
广度优先搜索都是用队列来写:
C语言的写完是这样的
void bfs(int x){ //bfs——广度优先遍历(x依然是第几号顶点,不过既然不递归其实传这个参数也没啥用)
queue <int> q; //没有队列那还叫广搜吗
q.push(x); //先把第一个顶点推进去,输出,标记访问过
cout<<x<<" ";
vis2[x]=1;
while(!q.empty()){ //广搜板子,上!
int fro=q.front(); //把队首取出来
for(int i=0;i<e[fro].size();i++){ //每条边去试
int point=s[e[fro][i]].v; //取终点(和dfs差不多)
if(!vis2[point]){ //没访问过,推进去,输出,标记
q.push(point);
cout<<point<<" ";
vis2[point]=1;
}
}
q.pop(); //队首搜完啦!把它弄出去
}
}
队列的作用就是将一个层次的节点给存入,先进先出的特点符合广度优先搜索的特点.