2016 藍橋杯省賽C語言B組 第六題 方格填數

他說少年如歌發表於2017-03-10
方格填數

如下的10個格子
+--+--+--+
| | | |
+--+--+--+--+
| | | | |
+--+--+--+--+
| | | |
+--+--+--+

(如果顯示有問題,也可以參看【圖1.jpg】)

填入0~9的數字。要求:連續的兩個數字不能相鄰。
(左右、上下、對角都算相鄰)

一共有多少種可能的填數方案?

請填寫表示方案數目的整數。

注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。


思路:  這道題和皇后的問題很像,不同的就是有兩個點是不能放的,那麼我們可以直接從(0, 1)開始查詢,以(2, 3)為結束條件

不懂得程式碼裡有註釋

答案是1580!!!!

程式碼:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define INF -0x3f3f3f3f
using namespace std;

int map[20][20], visit[20];
int n = 3, m = 4, ans;
///在向方格里填數的時候我們只用考慮已經填過數的格子裡的數是多少
///就可以了,不用判斷還未填數的格子 所以只用查詢上面四個格子即可
int dr[4][2] = {0,-1,-1,0,-1,1,-1,-1};
bool check(int x, int y, int num)
{
    for(int i = 0; i < 4; i++)
    {
        int nx = x + dr[i][0];
        int ny = y + dr[i][1];
        if(nx >=0&&nx < n&&ny >= 0&&ny < m)
        {
            if(map[nx][ny] == num - 1||map[nx][ny] == num + 1)
                return false;
        }
    }
    return true;
}
void dfs(int x, int y) ///行, 列
{
    if(x==2&&y==3)  ///因為(2, 3)也是缺口,終止條件
    {
        ans++;
        return;
    }
    if(y >= m)  ///如果列數大於等於4, 那麼就從下一行從頭開始
    {
        dfs(x + 1, 0);
    }
    else
    {
        for(int i = 0; i < 10; i++)
        {
            if(!visit[i]&&check(x, y, i))  ///判斷下一個點是否用過  在判斷是否越界  滿足題目的條件
            {
                visit[i] = 1;
                map[x][y] = i;
                dfs(x, y + 1);
                visit[i] = 0;
                map[x][y] = INF;
            }
        }
    }
}
int main()
{
    for(int i = 0; i <= 5; i++)
    {
        for(int j = 0; j <= 5; j++)
        {
            map[i][j] = INF;
        }
    }
    memset(visit, 0, sizeof(visit));
    ans = 0;
    dfs(0, 1);///因為(0,0)是缺口,所以從(0, 1)開始
    cout << ans << endl;
    return 0;
}



相關文章