2016藍橋杯省賽 方格填數

方格填數
如下的10個格子
   +--+--+--+
   |  |  |  |
+--+--+--+--+
|  |  |  |  |
+--+--+--+--+
|  |  |  |
+--+--+--+
(如果顯示有問題,也可以參看【圖1.jpg】)


填入0~9的數字。要求:連續的兩個數字不能相鄰。
(左右、上下、對角都算相鄰)
一共有多少種可能的填數方案?
請填寫表示方案數目的整數。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。

分析

搜索+判斷

#include<stdio.h>
#include<stdlib.h>
int v[12]={0},a[3][4],b[3][4],s=0;//v數字是否使用,a方格是否可填,b填入數據
 void solve()//判斷是否可行
 {
     int dir[8][2]={0,1,1,0,0,-1,-1,0,1,1,-1,-1,1,-1,-1,1};
     int f=0,i,j,k;
     for(i=0;i<3;i++)
        for(j=0;j<4;j++)
        if(a[i][j])
            for(k=0;k<8;k++)//循環判斷八個相鄰方向是否連續
        {
            int x=i+dir[k][0];
            int y=j+dir[k][1];
            if(x>2||x<0||y<0||y>3||!a[x][y])//如果越界就跳出本次循環
                continue;
            if(abs(b[x][y]-b[i][j])==1)//如果兩個數連續,就不符合要求
                f=1;
        }
        if(!f)
            s++;
 }
 void dfs(int n)//搜索所有填數方案
 {
     int x,y,i;
     x=n/4;//橫座標
     y=n%4;//豎座標
     if(x==3)//如果填數完成就判斷是否可行
     {
         solve();
         return;
     }
     if(a[x][y])//如果本座標可以填數
     {
         for(i=0;i<10;i++)//尋找沒有被使用的數字
            if(!v[i])
         {
             b[x][y]=i;//填入數字
             v[i]=1;//標記填入
            dfs(n+1);//進入下一層
            v[i]=0;//回溯
         }
     }
     else
        dfs(n+1);//如果填過或者不可填數,就直接進入下一層
 }
int main()
{
    int i,j;
    for(i=0;i<3;i++)
        for(j=0;j<4;j++)
        a[i][j]=1;//標記可填
    a[0][0]=a[2][3]=0;//特殊處理
    dfs(0);
   printf("%d\n",s);
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章