N nữ hoàng, X bởi câu hỏi phỏng vấn quyết định của hội đồng quản trị X


10

Tôi đã được hỏi câu hỏi sau đây trong một cuộc phỏng vấn ngày hôm nay và tôi đã suy nghĩ về nó kể từ đó. Tôi không thể trả lời và không thể tìm ra giải pháp trực tuyến.

Đưa ra một bàn cờ có kích thước X bởi các nữ hoàng Y và N, xác định xem có thể sắp xếp các nữ hoàng này trên bàn cờ sao cho họ không thể tấn công lẫn nhau.

Một bảng 2 x 3 với 2 nữ hoàng có một giải pháp để thuật toán sẽ trả về đúng:

Q . .
. . Q

Tôi đang tìm kiếm một cách tiếp cận lập trình cho câu đố này, không chỉ là cách để giải quyết nó trên giấy chẳng hạn.


Tìm kiếm đầu tiên tốt nhất chắc chắn là một lựa chọn, cũng như các tìm kiếm khác
Jason

2
được đề cử cho một trong những câu hỏi phỏng vấn tồi tệ nhất từ ​​trước đến nay - trừ khi phần mềm họ làm việc dựa vào các giải pháp quay lui, trong trường hợp đó hoàn toàn phù hợp
Steven A. Lowe

1
Công bằng mà nói, người phỏng vấn nói rằng đây đơn giản chỉ là một loại tín dụng bổ sung. Phần còn lại của cuộc phỏng vấn là IMO khá hợp pháp. Tôi chỉ là tò mò thôi.
Người được phỏng vấn

Có lẽ đó là một thử nghiệm nếu anh ta thực hiện một mô phỏng với quay lui hoặc (nghĩ về việc tìm) giải pháp O (1) bằng cách sử dụng các sự kiện được Caleb nêu trong câu trả lời của anh ta. Khả năng lập trình những điều đơn giản không phải là tất cả mọi thứ một người cần trong công việc.
Sốt

bài tập về nhà rõ ràng nằm ngoài phạm vi ở đây.
jwenting

Câu trả lời:


16

Đây không phải là (IMO) một vấn đề rất thú vị từ quan điểm lập trình. Bạn có thể đưa ra một thuật toán đệ quy thử mọi cách sắp xếp, đại loại như thế này:

bool try_queens(Board board, int n)
{
    if (n == 0) {
        // no queens left to place, so we're done
        return true
    }
    // try each open position until we find one that works
    for each position on the board {
        if (is_empty(board, position) and not is_attacked(board, position)) {
            place_queen(board, position)
            if (try_queens(board, n-1)) {
                return true
            }
            remove_queen(board, position)
        }
    }
    // if we get this far, there's no available position
    return false
}

main()
{
    initialize board(X,Y)
    return try_queens(board, N)
}

Nếu bạn nghĩ về vấn đề một chút, bạn sẽ nhận ra rằng không có cách nào phù hợp với N nữ hoàng trên một bảng trong đó X <N hoặc Y <N bởi vì điều đó sẽ yêu cầu ít nhất hai nữ hoàng kết thúc trong cùng một thứ hạng hoặc tệp, và do đó họ sẽ tấn công lẫn nhau. Nếu bạn đọc về vấn đề nữ hoàng, bạn sẽ nhanh chóng biết rằng luôn có thể đặt N nữ hoàng trên bảng NxN cho N> 3. Bây giờ chúng tôi biết rằng câu trả lời là KHÔNG cho (X <N hoặc Y <N) và CÓ cho (X> = N và Y> = N, N> 3). Tất cả những gì còn lại là những trường hợp đặc biệt:

  • N = 1 (CÓ)
  • N = 2 (CÓ cho X> = 2 và Y> 2 hoặc ngược lại)
  • N = 3 (CÓ cho X> = 3 và Y> 3 hoặc ngược lại)

Vì vậy, bây giờ hàm đệ quy tốt đẹp của chúng ta trở thành một hàm đơn giản chỉ cần so sánh N với X và Y và trả về kết quả đóng hộp. Đó là điều tuyệt vời từ quan điểm hiệu suất, vì bạn có thể nhận được câu trả lời trong thời gian liên tục. Theo quan điểm lập trình, nó không tuyệt vời lắm vì bạn nhận ra rằng, câu hỏi thực sự là về cách bạn có thể giải các câu đố tốt hơn khả năng viết một hàm đệ quy.

(Và chàng trai ơi, tôi thực sự hy vọng rằng tôi đã không phạm phải một số sai lầm ngớ ngẩn trong câu trả lời thông minh của mình .--)


That's great from a performance point of view, since you can get an answer in constant time. It's not so great from a programming point of view because you realize, at this point, that the question is really more about how well you can solve puzzles than it is about your ability to write a recursive function.Tôi thực sự nghĩ rằng người phỏng vấn đang chờ đợi giải pháp O (1) đó vì nó cuối cùng tốt hơn và không rõ ràng đối với nhiều người. Vấn đề nữ hoàng nxn có trong tất cả các khóa học lập trình như là một bài tập để đệ quy - nhiều người sẽ không nghĩ sâu hơn khi gặp lại vấn đề đó.
Sốt

4

Nếu người phỏng vấn đã yêu cầu bạn viết mã cho vấn đề, thì tôi nghĩ rằng nó không công bằng. Thuật toán yêu cầu công việc. Tuy nhiên, nếu ý tưởng là chỉ cho người phỏng vấn các lớp, phương pháp hoặc một số khái niệm mà bạn cần sử dụng hoặc một cái gì đó tương tự, thì đó có thể là một câu hỏi công bằng.

Vấn đề là một vấn đề Khoa học Máy tính cổ điển và được thảo luận trong nhiều cuốn sách như vậy. Một lời giải thích tuyệt vời, với hình ảnh động và 12 giải pháp khác nhau cùng với một số mã có thể được tìm thấy ở đây:

http://en.wikipedia.org/wiki/Eight_queens_puheads

Ngoài ra mã có thể được tìm thấy ở đây: http://www.codeproject.com/KB/java/EightQueen.aspx

Đừng cảm thấy tồi tệ về điều này, như tôi đã nói, nó không phải là một điều dễ dàng.


0

Đây thực sự là một nhận xét nhiều hơn, nhưng nó không phù hợp ở đó ...

Một bàn cờ có 8 ô vuông, không hơn không kém (những câu hỏi này luôn làm tôi khó chịu với cách tiếp cận của bàn cờ tùy chỉnh).

Nhưng dù sao đi nữa, nếu bạn có một bàn cờ x * y, và n nữ hoàng và lấy đó là nữ hoàng "lấy" những lĩnh vực này

nhập mô tả hình ảnh ở đây

bạn có thể chỉ cần tạo một mảng hai chiều và "gắn cờ" tất cả các trường mà một nữ hoàng tấn công. Sau đó đặt một cái khác (từ giữa bảng), gắn cờ các trường còn lại, v.v ... cho đến khi bạn chạy một trong các trường hoặc kiến ​​trúc.

Tất nhiên đây là một cách tiếp cận rất đơn giản, vì nếu định vị theo cách xấu, tôi tập hợp số lượng nữ hoàng tối đa sẽ thay đổi.

Hmm, chỉ tìm thấy điều này là tốt - vấn đề 8 nữ hoàng.


Tôi đã đề xuất thuật toán chính xác này lúc đầu nhưng xem xét rằng bạn không đảm bảo rằng nếu bạn thực hiện phương pháp này và cuối cùng bạn không có nơi nào để đặt Nữ hoàng cuối cùng của bạn mà bạn thực sự đã xác định là không thể. Bạn chỉ loại bỏ sự sắp xếp đặc biệt đó. Đây về cơ bản là một ứng dụng của heuristic láng giềng gần nhất.
Người được phỏng vấn

@Interviewee - Vâng, tôi biết. Đây chỉ là một cái gì đó tôi nghĩ ra khỏi đỉnh đầu của tôi. Như đã nói, đó là một vấn đề thú vị và có thể được cải thiện, nhưng trong 4 giờ sáng (ở đây) tôi chỉ quá lười biếng để suy nghĩ. Btw, cuộc phỏng vấn đã diễn ra như thế nào?
Rook

@Interviewee, đây là ý kiến ​​đúng. Điều còn thiếu là nếu bạn phát hiện ra không có chỗ cho nữ hoàng cuối cùng, bạn sẽ sao lưu và thử một vị trí khác cho vị trí thứ hai đến nữ hoàng cuối cùng. Nếu không có nơi nào cho nữ hoàng đó cho phép sắp xếp nữ hoàng cuối cùng, bạn hãy sao lưu một cấp độ khác và thử một vị trí khác cho vị trí thứ ba đến nữ hoàng cuối cùng, v.v.
Caleb

Tôi thích hình đại diện của bạn là một quân cờ :)
warren

0

Về cơ bản, thuật toán quay lui hoạt động như thế này:

  1. Tạo một mảng X by Y. Đặt tất cả các hình vuông thành trống.

  2. Đặt số nữ hoàng về không.

  3. Đặt vị trí hiện tại của bạn thành (1,1)

  4. Xem nếu bạn có thể đặt một nữ hoàng ở vị trí hiện tại.

  5. Nếu bạn có thể, hãy đặt Mảng (X, Y) thành nữ hoàng, tăng số lượng nữ hoàng. Nếu bạn đặt tất cả nữ hoàng, dừng lại , bạn có một giải pháp.

  6. Nếu vị trí hiện tại không (X, Y), hãy tăng vị trí hiện tại và chuyển sang bước 4.

  7. Tìm nữ hoàng ở vị trí cuối cùng (người đến sau theo thứ tự bạn tăng vị trí). Đặt vị trí hiện tại vào vị trí của nữ hoàng đó, loại bỏ nó và giảm số lượng nữ hoàng.

  8. Nếu số nữ hoàng bằng không, dừng lại , không có giải pháp.

  9. Tăng vị trí hiện tại.

  10. Chuyển đến bước 4.


Trong mô tả này, thuật toán không quay lại chính xác: nó chỉ loại bỏ nữ hoàng có thể xoa dịu cuối cùng; bạn có nguy cơ không bao giờ thử các nữ hoàng trước đó ở các vị trí khác.
Kasper van den Berg

@KaspervandenBerg Quay lại thuật toán chính xác. Tôi sẽ trả lời trực tiếp những lời chỉ trích của bạn, nhưng tôi thực sự không thể hiểu điều đó. Tôi không biết ý của bạn là "nữ hoàng dễ dãi cuối cùng". Nó sẽ chỉ loại bỏ nữ hoàng được đặt cuối cùng, nhưng bất kỳ nữ hoàng nào cũng có thể trở thành nữ hoàng được đặt cuối cùng một khi nữ hoàng được đặt sau khi nó bị loại bỏ. Nó sẽ quay lại khi cần thiết, loại bỏ các nữ hoàng theo thứ tự ngược lại với thứ tự họ đã đặt.
David Schwartz

0

Thêm vào các câu trả lời khác: tạo một mảng hai chiều chỉ làm phức tạp mã.

Bạn chỉ cần một vectơ kích thước 8 cho một bàn cờ thông thường. Hoặc 8 + 1 nếu như vị trí thứ 1 của C là 0, chỉ để đơn giản hóa mã và xử lý với số 1 chứ không phải 0-7.

Nếu bạn nghĩ về x là vị trí của bạn trong mảng và y là nội dung của vị trí. ví dụ: bảng [1] = 8 có nghĩa là nữ hoàng đầu tiên ở [1,8].

Theo cách đó, bạn chỉ cần kiểm tra xác thực cột.

Vào thời gian giảng viên, tôi đã bắt gặp một cuốn sách rất cũ (thập niên 60?), Về các thuật toán được triển khai trong Dartmouth BASIC, đã thực hiện bài toán 8 nữ hoàng bằng cách sử dụng ít bộ nhớ hơn (có thể là cũ, nó có ý nghĩa).

Theo tôi nhớ, nó đã sử dụng ý tưởng vectơ, và về cơ bản, nó đã buộc tất cả các vị trí trong bảng với hai chu kỳ FOR. Để kiểm tra tính hợp lệ của vị trí, nó đã sử dụng vòng lặp thứ ba, chu trình WHILE ở mỗi vị trí quay trở lại trong vectơ và kiểm tra một số bằng nhau hoặc cho một công thức sử dụng thao tác tiếp tuyến để kiểm tra các đường chéo.

Đáng buồn thay, tôi đã mất dấu cuốn sách đó ...

Thuật toán cho biết đã tìm thấy tất cả các giải pháp cho vấn đề n-queen.


0

Nếu bạn chỉ cần viết một thuật toán để xác định xem có tồn tại một sự sắp xếp như vậy hay không, thì hãy xem nghiên cứu hiện có:
Câu đố tám nữ hoàng trên Wikipedia .

Bạn có thể trả về giá trị false nếu N> min (X, Y).
Sau khi đọc trang đó, bạn biết trả về true nếu N <= min (X, Y) và 2, 3! = Min (X, Y).

Mà lá 2, 3 == min (X, Y) và N <= min (X, Y).

Chà, nếu N <min (X, Y), việc tìm giải pháp là chuyện nhỏ.
Nếu N == min (X, Y), chỉ có một giải pháp nếu max (X, Y)> N.

f(X, Y, N)
    if X < Y => f(Y, X, N)
    if Y > N => false
    => (Y < N) or (Y != 2 and Y != 3) or (X > N)

0

Rõ ràng là không có giải pháp nếu N> min (X, Y). Mặt khác, bạn có thể dễ dàng chỉ ra rằng không có giải pháp nào cho N = X = Y = 2, N = X = Y = 3. Đối với tất cả các trường hợp khác dường như có một giải pháp. Số lượng các giải pháp dường như tăng lên khi N tăng trưởng.

Bạn có thể tìm thấy giải pháp thông qua tìm kiếm toàn diện với quay lui: Đặt một nữ hoàng ở hàng đầu tiên, cột 1. Đặt một nữ hoàng ở hàng thứ hai, trong cột đầu tiên mà nữ hoàng ở hàng 1 không thể với tới. Đặt một nữ hoàng ở hàng thứ hai, v.v ... Nếu một nữ hoàng không thể được xếp vào hàng k, thì bạn loại bỏ nó và di chuyển nữ hoàng ở hàng k-1 ở vị trí không có người tiếp theo.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.