I.像素放置【蓝桥杯】/dfs+剪枝

像素放置




dfs+剪枝

思路:利用dfs填入0或者1,并利用数字进行判断,另外这一题数组要从1开始而不是0,这样在num方法中可以少了判断的操作

cpp 复制代码
#include<iostream>
using namespace std;
//a数组存储输入的值,下划线则为-1
//ans数组存储填的01值
int a[15][15],ans[15][15];
bool flag=0;
int n,m;
int b[9][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,0},{0,1},{1,-1},{1,0},{1,1}};
//判断该数字格子周围九个点是否符合
bool num(int x,int y)
{
    int res=0,big=a[x][y];
    for(int i=0;i<9;i++)
    {
        int xx=x+b[i][0];
        int yy=y+b[i][1];
        if(ans[xx][yy]==1) res++;
        if(res>big) return 0;
    }
    return res==big;
}
//检查某个点之前的数字点是否符合
bool checksub(int x,int y)
{
    //假设到了x,y点,则x-2这一行及前面的九个格都已经填完
    //细节:要从后往前遍历,否则会超时两个案例,因为其实前面有的已经判断过了,先判断后面的更快找到不符合的
    for(int i=x-2;i>=1;i--)
    {
        for(int j=m;j>=1;j--)
        {
            if(a[i][j]==-1) continue;
            if(!num(i,j)) return 0;
        }
    }

    //x上一行y-2列及前面列周围九个格都已经填完
    if(x>=2)
    {
        for(int j=y-2;j>=1;j--)
        {
            if(a[x-1][j]==-1) continue;
            if(!num(x-1,j)) return 0;
        }
    }
    return 1;
}
//检查所有格子是否符合
bool checkall()
{
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(a[i][j]==-1) continue;
            if(!num(i,j)) return 0;
        }
    }
    return 1;
}
void dfs(int x,int y)
{
    //flag为1,表示已经找到唯一的解,直接返回
    if(flag) return ;
    if(!checksub(x,y)) return ;
    //全部遍历完
    if(x==n+1)
    {
        if(checkall())
        {
            flag=1;
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    printf("%d",ans[i][j]);
                }
                printf("\n");
            }
            return ;
        }
        return ;
    }
    //遍历到最后一列
    if(y==m)
    {
        ans[x][y]=1;
        dfs(x+1,1);
        ans[x][y]=0;
        dfs(x+1,1);
        return ;
    }
    ans[x][y]=1;
    dfs(x,y+1);
    ans[x][y]=0;
    dfs(x,y+1);
    return ;
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            char ch;
            cin>>ch;
            if(ch=='_') a[i][j]=-1;
            else a[i][j]=ch-'0';
        }
    }
    dfs(1,1);
    return 0;
}
相关推荐
有毒的教程2 天前
Dev-C++ 避免爆栈(Stack Overflow)完整方案
c++·算法·深度优先
一条大祥脚3 天前
26ICPC网络赛第二场 计数|DFS|MEX|贪心
算法·深度优先·mex·icpc网络赛
yi0114 天前
DAY22: LeetCode 733:图像渲染——从二维网格开始理解 DFS 和 BFS
数据结构·笔记·python·算法·leetcode·深度优先·宽度优先
智者知已应修善业4 天前
【51单片机只有一个8*8点阵数据如何滚动起来一片595+一组IO+花样】2022-1-15
c++·经验分享·笔记·单片机·蓝桥杯·硬件架构
CQU_JIAKE6 天前
10.3【A】
深度优先
言乐66 天前
Python区分广度优先深度优先宽度优先的区别
python·算法·深度优先·广度优先·宽度优先
Dream it possible!7 天前
蓝桥杯_翻转_C++
c++·算法·蓝桥杯
RobinDevNotes8 天前
大模型3D并行训练怎么配才不浪费算力
网络·人工智能·深度学习·深度优先
一条大祥脚8 天前
26 ICPC上海 交互|二分|重心|构造|二分图|贪心|SOSDP|三进制枚举|线性基|字典序贪心|DFS|分块|单侧递归线段树
算法·深度优先·交互·分块·icpc上海站·单侧递归线段树
Doubbbbbbble云9 天前
图算法中的剪枝技术与启发式优化分析4
算法·机器学习·剪枝