BFS 滑雪和八皇后问题

题目:

1、滑雪
Michael喜欢滑雪这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道在一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-…-3-2-1更长。事实上,这是最长的一条。
Input
输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。
Output
输出最长区域的长度。
Sample Input
5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
Sample Output
25

y_,x_=map(int,input().split(' '))
nums=[]
for i in range(y_):
	nums.append(list(map(int,input().split(' '))))
c=[[0 for a in range(x_)] for b in range(x_)]# 用于记录每个位置最多能往下划多少。
def check(y,x):
	move=[[-1,0],[+1,0],[0,+1],[0,-1]]
	if c[y][x]!=0:
		return c[y][x]
	count=1  
	for a,b in move:
		ny=y+a
		nx=x+b
		if 0<=ny<y_ and 0<=nx<x_ and nums[y][x]>nums[ny][nx]:
			count=max(count,check(ny,nx)+1)
	c[y][x]=count#将结果记录
	return c[y][x]#返回当前结果与上一次的最大长度进行比较。
            
res=0
for y in range(y_):
    for x in range(x_):
        res=max(res,check(y,x))
print(res)

结果:
在这里插入图片描述

题目:

2、八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当 n = 1 或 n ≥ 4 时问题有解。
Input
无输入。
Output
按给定顺序和格式输出所有八皇后问题的解(见Sample Output)。
Sample Input
Sample Output
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
No. 3
1 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 1
0 0 1 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0
0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0
No. 4
1 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0
0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0
No. 5
0 0 0 0 0 1 0 0
1 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 0 0 0 0 1
0 0 1 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0
No. 6
0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 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 0 0 0 1 0
0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0
No. 7
0 0 0 0 1 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 1 0 0 0 0
0 1 0 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0
No. 8
0 0 1 0 0 0 0 0
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
No. 9
0 0 0 0 1 0 0 0
1 0 0 0 0 0 0 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 0 0 1 0
0 0 1 0 0 0 0 0
…以下省略

代码:

queen = [None]*8
sum = 0


def check(queen, y):  # 只需要检测从第0行到当前已经放置的行数。
    for i in range(y):
        # 判断是否不要同行的有在同一列的情况  或者  成对角线放置的情况。
        if queen[i] == queen[y] or abs(i-y) == abs(queen[i]-queen[y]):
            return False
    return True


def put(queen, y):
    global sum
    if y == len(queen):  # 如果能够经过检测放到最后一行就是一种新的放置方法。
        sum += 1
        return sum
    for k in range(len(queen)):  # k代表列数
        queen[y] = k  # 寻找在当前行有哪些列可以放置queen,所以把列的值赋给当前行数的queen。
        if check(queen, y):
            put(queen, y+1)
put(queen, 0)
print(sum)

结果:92

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是使用 BFS 算法来解决 n 皇后问题的 C 代码实现: ```c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define MAX_N 100 // 皇后的位置 typedef struct { int x; // 行 int y; // 列 } Queen; // 状态 typedef struct { Queen queens[MAX_N]; // 皇后的位置 int n; // 皇后的数量 } State; // 队列 typedef struct { State states[MAX_N * MAX_N]; int front, rear; } Queue; // 初始化队列 void initQueue(Queue *q) { q->front = q->rear = 0; } // 判断队列是否为空 bool isEmpty(Queue *q) { return q->front == q->rear; } // 入队 void enqueue(Queue *q, State *s) { q->states[q->rear++] = *s; } // 出队 void dequeue(Queue *q, State *s) { *s = q->states[q->front++]; } // 判断两个皇后是否有冲突 bool conflict(Queen *q1, Queen *q2) { return q1->x == q2->x || q1->y == q2->y || abs(q1->x - q2->x) == abs(q1->y - q2->y); } // 判断状态是否合法 bool isValid(State *s) { for (int i = 0; i < s->n; i++) { for (int j = i + 1; j < s->n; j++) { if (conflict(&s->queens[i], &s->queens[j])) { return false; } } } return true; } // 打印状态 void printState(State *s) { for (int i = 0; i < s->n; i++) { for (int j = 0; j < s->n; j++) { if (s->queens[i].y == j) { printf("Q "); } else { printf(". "); } } printf("\n"); } printf("\n"); } // 解决 n 皇后问题 void solve(int n) { State initial; initial.n = n; for (int i = 0; i < n; i++) { initial.queens[i].x = 0; initial.queens[i].y = i; } Queue q; initQueue(&q); enqueue(&q, &initial); State current; while (!isEmpty(&q)) { dequeue(&q, &current); if (current.n == n && isValid(&current)) { printState(&current); } else { for (int i = 0; i < n; i++) { State next = current; next.queens[next.n].x = next.n; next.queens[next.n].y = i; next.n++; enqueue(&q, &next); } } } } int main() { int n; printf("请输入皇后的数量:"); scanf("%d", &n); printf("%d 皇后问题的解为:\n", n); solve(n); return 0; } ``` 上述代码中,使用了一个 `State` 结构体来表示状态,其中包含了当前放置的皇后的位置和数量。使用一个队列来存储状态,初始状态为第一行的皇后都放在不同的列中。在每次出队时,将当前状态的下一行所有可能放置的位置都入队,直到找到一个合法的解为止。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值