方格填数--蓝桥杯---dfs

一,第六届蓝桥杯C语言初赛

答案:1580

相似题目:N皇后问题

注意要枚举的是什么

#include<iostream>
#include<string.h>
using namespace std;
int a[3][4],vis[10],dir[4][2]={{0,-1},{-1,-1},{-1,0},{-1,1}};
int cnt=0;
int check(int x,int y,int num)
{
    for(int i=0;i<4;i++)
    {
        int tx,ty;
        tx=x+dir[i][0];
        ty=y+dir[i][1];
        if(tx>=0&&tx<3&&ty>=0&&ty<4)
        {
            if(a[tx][ty]==num-1||a[tx][ty]==num+1)//不相邻
                return 0;
        }
    }
    return 1;
}

void dfs(int x,int y)
{
    if(x==2&&y==3)
    {
        cnt++;
        return;
    }
    if(y>3)//当前行搜索完
        dfs(x+1,0);
    else
    {    
        for(int i=0;i<10;i++)
        {
            
            if(check(x,y,i)&&!vis[i])//在棋盘上并且没有相邻/这个数字没有用过
            {
                a[x][y]=i;
                vis[i]=1;
                dfs(x,y+1);
                a[x][y]=12;//回溯
                vis[i]=0;
            }
        }
    }
}
int main()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<4;j++)
        {
            a[i][j]=12;
        }
    }
    dfs(0,1);
    cout<<cnt<<endl;
    return 0;
}

二、第六届C语言蓝桥杯决赛

答案:42

 题解一:模拟+暴力

//答案:42
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int main()
{
    int a[12],mp[3][6];
    mp[0][5]=mp[1][5]=100;//处理边界
    for(int i=0;i<5;i++)
        mp[1][i]=100;
    for(int i=0;i<10;i++)
        a[i]=i+1;
    int ans=0;
    do
    {
        if(a[0]<a[1]&&a[1]<a[2]&&a[2]<a[3]&&a[3]<a[4])
        {
            if(a[5]<a[6]&&a[6]<a[7]&&a[7]<a[8]&&a[8]<a[9])
            {
                if(a[0]<a[5]&&a[1]<a[6]&&a[2]<a[7]&&a[3]<a[8]&&a[4]<a[9])
                    ans++;
            }
        }
    }while(next_permutation(a,a+10));
    cout<<ans<<endl;
    //system("pause");
    return 0;
}

题解二:DFS(过程同上题)

#include<iostream>
#include<string>
#include<string.h>
using namespace std;
int a[2][5], vis[12];
int cnt = 0;
int check(int x, int y)
{
    if(x==0&&y==0)//注意边界
        return 1;
    else if(x==1&&y==0&&a[1][0]>a[0][0])
        return 1;
    else if(x==0&&a[x][y-1]<a[x][y])
        return 1;
    else if(x==1&&a[x][y-1]<a[x][y]&&a[x-1][y]<a[x][y])
        return 1;
    else
    {
        return 0;
    }
    
}

void dfs(int x, int y)
{
    if (x == 2)//棋盘放满
    {
        cnt++;
        return;
    }
    if (y > 4)//当前行搜索完
        dfs(x + 1, 0);
    else
    {
        for (int i = 1; i <= 10; i++)
        {

            if (vis[i]==0)//这个数字没有用过,并且符合条件
            {
                a[x][y] = i;
                vis[i] = 1;
                if(check(x,y)) 
                    dfs(x, y + 1);
                vis[i] = 0;//回溯
            }
        }
    }
}
int main()
{
    memset(vis, 0, sizeof(vis));
    dfs(0, 0);
    cout << cnt << endl;
    system("pause");
    return 0;
}
原文地址:https://www.cnblogs.com/-citywall123/p/10519842.html