这道题的描述应该是有问题的(不知道是原文的问题还是翻译的问题)。
前面的描述中提到“前后左右的座位全是异性”和NG示例中的“前后左右全是同性”两种情况。问题中所要求满足的“上述条件”是什么呢?仅从上下文来看第一感当然是说“前后左右的座位全是异性”。但是仔细一想就知道这个不对,每个座位的“前后左右的座位都是异性”的安排情况只有两种。
“前后左右的座位全是异性”和“前后左右全是同性”的两种极端情况之间还有巨大的灰色空间。问题的原意应该是指满足“任何一个座位的前后左右不全是同性(或至少有一个异性)”的情况吧?
先考虑一个基本方案。
从搜索方式来说,这个问题与前面的Q32和Q59等题有类似之处。只需要基于Q32或Q59的基本框架略作修改即可。
要点说明:
- # -*- coding: utf-8 -*-
- """
- Created on Tue Oct 19 07:39:48 2021
-
- @author: chenxy
- """
-
- import sys
- import time
- import datetime
- import math
- # import random
- from typing import List
- from collections import deque
- import itertools as it
- import numpy as np
-
- H = 5 # Height, vertical
- W = 6 # Width, horizontal
-
- # seats initialization, with a guard band surrounding the original seats
- # The guard band is initialized to '-1' to simplify the judgement processing.
- seats = np.zeros((H+2, W+2))
- seats[0,:] = -1
- seats[H+1,:] = -1
- seats[:,0] = -1
- seats[:,W+1] = -1
-
- count = 0
-
- def isNG(h,w):
- if seats[h,w] == -1:
- return False
- return (seats[h+1,w]==seats[h,w] or seats[h+1,w]==-1) and \
- (seats[h-1,w]==seats[h,w] or seats[h-1,w]==-1) and \
- (seats[h,w+1]==seats[h,w] or seats[h,w+1]==-1) and \
- (seats[h,w-1]==seats[h,w] or seats[h,w-1]==-1)
-
-
- def arrange_seat(h,w, boy, girl)->int:
- '''
- Parameters
- ----------
- (h,w) : The current exploration point.
- h represents row index, w represents col index.
- Returns: int
- The number of total arrangement starting from the point (h,w), together
- with the current seats status, which is a global variable
-
- '''
- global count
- # print('h = {0}, w = {1}'.format(h,w))
- if h == H + 1:
- if boy == girl:
- count = count + 1
- # print(seats)
- elif w == W + 1: # Go to the next row.
- # Reach the right boundary, go to explore the next row from the left
- arrange_seat(h+1, 1, boy, girl)
- # elif seats[h,w] > 0:
- # # This grid has been occupied, move to the right one
- # arrange_seat(h, w+1)
- else:
- # Try to arrange boy to the current seat(h,w)
- seats[h,w] = 1
- if not (isNG(h-1,w) or isNG(h,w-1) or isNG(h,w)):
- arrange_seat(h,w+1, boy+1, girl)
- seats[h,w] = 0
- # Try to arrange girl to the current seat(h,w)
- seats[h,w] = 2
- if not (isNG(h-1,w) or isNG(h,w-1) or isNG(h,w)):
- arrange_seat(h,w+1, boy, girl+1)
- seats[h,w] = 0
-
- tStart = time.perf_counter()
- arrange_seat(1, 1, 0, 0)
- tCost = time.perf_counter() - tStart
- print('count = {0}, tCost = {1:6.3f}(sec)'.format(count,tCost))
运行结果:
[3,4]: count = 354, tCost = 0.014(sec)
[4,5]: count = 34874, tCost = 1.649(sec)
[5,6]: count = 13374192, tCost = 803.130(sec)
跟昨天的Q69一样,给出一个功能正确的方案并不难,但是运行太慢了!所以这些问题的难点在于如何提高运行效率,比如说书中所提示的剪枝,还有memoization等啊?容我再想一想。。。