如下的10个格子
填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
解:回溯法,类似于数独那题,填每个数时判断是否存在冲突,不存在就可以继续填下一位置,结果是1580,c++代码:
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
int leftAndRight[7] = {0, 1, 3, 4, 5, 7, 8};
int upAndDown[6] = {0, 1, 2, 3, 4, 5};
int rightDown[4] = {0, 1, 3, 4};
int leftDown[6] = {0, 1, 2, 4, 5, 6};
int result = 0;
vector<int> board;
bool inVec(int num) {
for (int i = 0; i < board.size(); i++)
if (board[i] == num) return true;
return false;
}
bool isConflict(int pos) {
for (int i = 0; i < 7; i++) {
if (leftAndRight[i]+1 <= pos) {
if (abs(board[leftAndRight[i]] - board[leftAndRight[i]+1]) == 1) return true;
}
}
for (int i = 0; i < 6; i++) {
if (upAndDown[i] + 4 <= pos) {
if (abs(board[upAndDown[i]] - board[upAndDown[i]+4]) == 1) return true;
}
}
for (int i = 0; i < 4; i++) {
if (rightDown[i] + 5 <= pos) {
if (abs(board[rightDown[i]] - board[rightDown[i]+5]) == 1) return true;
}
}
for (int i = 0; i < 6; i++) {
if (leftDown[i] + 3 <= pos) {
if (abs(board[leftDown[i]] - board[leftDown[i]+3]) == 1) return true;
}
}
return false;
}
void solve(int pos) {
cout << board.size() << endl;
if (pos == 9) {
for (int i = 0; i < 10; i++) {
if (!inVec(i)) {
board.push_back(i);
if (!isConflict(9)) result++;
board.pop_back();
break;
}
}
return;
}
for (int i = 0; i < 10; i++) {
if (!inVec(i)) {
board.push_back(i);
if (!isConflict(pos)) solve(pos+1);
board.pop_back();
}
}
return;
}
int main() {
solve(0);
cout << result;
return 0;
}