第七屆藍橋杯C\C++B組省賽題目——方格填數


第一部分:題目

方格填數

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

(如果顯示有問題,也可以參看下圖)



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

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

請填寫表示方案數目的整數。
注意:你提交的應該是一個整數,不要填寫任何多余的內容或說明性文字。

第二部分:思路

這個題目有點表述不明,不知道0~9 可不可以重復使用。現在看來是不能重復使用的。
我的做法是把表格當做3行4列的數組,去掉一頭一尾。
步驟:填數字->判斷是否滿足要求:相鄰位置數字不能相鄰。
需要注意的地方:保證數字沒有重復使用:借助數組take,存儲使用的數字,當所要填寫的數字不在數組中時才可以填入。填入后存進數組。
                       判斷是否滿足相鄰位置數字不能相鄰的要求。看代碼注釋。
答案是: 1580
第三部分:代碼
#include<stdio.h>
#include<stdlib.h>
int count=0;
int take[10],index=0;//記錄當前已經填入的數字,用於填數字前判斷是否已經使用,避免重復使用 
int is_legal(int s[3][4])//判斷是否滿足要求:相鄰位置數字不能相鄰,就是兩數字的差大於1.就是為什么s[0][0]、s[2][3]置為-2;
{
    //這里的判斷方法有點死板。假設每個位置都有上下左右和對角,只需要判斷這些位置
    //是不是在數組中,在就進行比較,不在就說明沒有。 
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<4;j++)
        {
            if(j-1>=0)
            {
                if(abs(s[i][j]-s[i][j-1])==1)
                {
                    return 0;
                }
            }
            if(j+1<4)
            {
                if(abs(s[i][j]-s[i][j+1])==1)
                {
                    return 0;
                }
            }
            if(i+1<3)
            {
                if(abs(s[i][j]-s[i+1][j])==1)
                {
                    return 0;
                }
            }
            if(j-1>=0&&i+1<3)
            {
                if(abs(s[i][j]-s[i+1][j-1])==1)
                {
                    return 0;
                }
            }
            if(j+1<4&&i+1<3)
            {
                if(abs(s[i][j]-s[i+1][j+1])==1)
                {
                    return 0;
                }
            }
            if(i-1>=0&&j+1<4)
            {
                if(abs(s[i][j]-s[i-1][j+1])==1)
                {
                    return 0;
                }
            }
            if(i-1>=0)
            {
                if(abs(s[i][j]-s[i-1][j])==1)
                {
                    return 0;
                }
            }
            if(j-1>=0&&i-1>=0)
            {
                if(abs(s[i][j]-s[i-1][j-1])==1)
                {
                    return 0;
                }
            }
        }
    } 
    return 1;
}
void fun(int s[3][4],int a,int b)
{
    int i;
    if(a==2&&b==3)//表示當前已經填滿了表格,需要進行判斷看是否滿足要求 
    {
        if(is_legal(s))
        {
            count++;
        }
    }
    else//繼續填寫 
    {
        for(i=0;i<=9;i++)
        {
            int j;
            for(j=0;j<index;j++)//填寫的數字必須是沒有用過的 
            {
                if(i==take[j])
                {
                    break;
                }
            }
            if(j==index)
            {
                s[a][b]=i;
                take[index++]=i;
                if(b<3)//表示當前行還沒填完 
                {
                    fun(s,a,b+1);
                }
                else//當前行填完就從下一行開始 
                {
                    if(a<2)//判斷當前行是否是最后一行 
                    {
                        fun(s,a+1,0);
                    }
                }
                index--;//在一次填滿結束后,當前位置的數字換為其他可以填寫的數字
                        //所以當前使用的數字需要出去。 
            }
        } 
    }
}
int main()
{
    int s[3][4];
    s[0][0]=-2;
    s[2][3]=-2;
    //左上角和右下角沒有,為了方便判斷把數值設為-2(小於-1大於10均可) 
    fun(s,0,1);
    printf("%d\n",count);
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM