平板涂色(dfs)

文章描述了一个关于自动喷漆机APM的问题,它需要在平面板上用不同颜色的矩形覆盖整个区域。每个矩形有特定的颜色代码,且必须按照从上到下的顺序涂色,不能有重叠。给定矩形的信息,目标是找到最小的画笔拾取次数来完成涂色。解决方案涉及到使用深度优先搜索(DFS)策略,通过回溯找到满足条件的最小画笔更换次数。
摘要由CSDN通过智能技术生成

平板涂色

题目描述

CE 数字公司已经建立了一个自动喷漆机 (APM), 以绘制一个平面板完全覆盖的相邻的不同大小的非重叠矩形每一个预定义的颜色。

为了给主板上色, APM 可以访问一组画笔。每个画笔都有一个不同的颜色 C。APM 使用颜色 c 选择一个画笔, 并绘制所有可能的具有预定义颜色 c 的矩形, 并
具有以下限制: 为了避免泄漏颜料和混合颜色, 只有在上面的所有矩形都有已经被粉刷过了。

例如, 在图1中标记为 F 的矩形在绘制矩形 C 和 D 之后才被绘制。请注意, 必须同时绘制每个矩形, 即不允许对一个矩形进行部分绘制。
您要编写一个用于 APM 的程序来绘制给定的主板, 以使画笔拾取的数量最小。请注意, 如果一个画笔多次被拾取, 所有的拾取都将被计数。

输入

 输入文件的第一行包含整数 N, 矩形的数目, 后跟描述矩形的 n 行。每个矩形 R 在一行中指定为5个整数: r 左上角的 y 和 x 坐标, r 右下角的 y 和 x 坐标, 后跟 r 的颜色代码.
请注意:

  1. 颜色代码是一个整数, 范围为1。20。
  2. 板坐标的左上角总是 (00)。
  3. 坐标在范围 0..。99。
  4. N 的范围为 1.. 15。

输出

一行, 显示画笔拾取的最小数目

样例输入

7
0 0 2 2 1
0 2 1 6 2
2 0 4 2 1
1 2 4 4 2
1 4 3 6 1
4 0 6 4 1
3 4 6 6 2

样例输出

3

说明/提示

1≤Ci​≤20,0≤xi​,yi​≤99,1≤N≤16。

思路:

别人的思路:

  • 先用结构体记录数据
  • 然后循环记录(记录一个矩形的上面需要涂的矩形)
  • 深搜并且回溯

我的思路:

  • 具体看代码,代码里有注释

代码:

#include<bits/stdc++.h>
using namespace std;
struct candy{
	int x1,y1,x2,y2,col;//结构体输入
}pd[51];
vector<int> dp[51];//可变数组
int n,ans=2147483647,vis[51];
inline int check(int w){//判断是否上边的都涂完了
	int t=dp[w].size();//数上面有几个矩形
	for(int i=0;i<t;++i){//分别对每一个矩形判断
		if(vis[dp[w][i]]==0) return 0;//有一个没涂上就不符合要求,输出0(╥﹏╥)
	}
	return 1;//都符合就输出1(*^▽^*) 
}
inline void dfs(int cnt,int sum,int cl){//cnt是涂的个数,sum是换的次数,col是上一次的颜色
	if(cnt==n){//如果都涂上颜色了就比大小记录最短值
		ans=min(ans,sum);
		return ;
	}
	if(sum>=ans) return ;//剪枝,如果没涂完就比答案大了就没必要继续搜了
	for(int i=1;i<=n;++i){//找可以涂的矩形枚举
		if(vis[i]==0&&check(i)==1){//没涂过并且可以涂
			vis[i]=1;//标记涂过
			dfs(cnt+1,sum+(cl!=pd[i].col),pd[i].col);//个数++,颜色变了就++,记录颜色
			vis[i]=0;//撤销标记回溯
		}
	}
}
int main(){
	cin>>n;//输入
	for(int i=1;i<=n;++i){
		cin>>pd[i].x1>>pd[i].y1>>pd[i].x2>>pd[i].y2>>pd[i].col;//输入
	}
	for(int i=1;i<=n;++i){
		for(int j=1;j<=n;++j){
			if(i!=j&&pd[i].x1==pd[j].x2&&(pd[i].y2>=pd[j].y1&&pd[i].y1<=pd[j].y2))/*判断两个矩形有无先后顺序(1.下底面对应上顶面;2.左右是否相等)*/ dp[i].push_back(j);//如果有先后顺序就放入数组
		}
	}
	dfs(0,0,0);//深搜
	cout<<ans;//输出
	return 0;//养成好习惯
}

本题解制作不易,点个赞吧,蟹蟹(✪ω✪)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值