每日一宏
#define 大法师 dfs
大法师万岁
题目
题目描述
CE 数码公司开发了一种名为自动涂色机(APM)的产品。它能用预定的颜色给一块由不同尺寸且互不覆盖的矩形构成的平板涂色。
为了涂色,APM 需要使用一组刷子。每个刷子蘸了颜色 C 。APM 拿起一把蘸有颜色 C 的刷子,并给所有颜色为 C 的矩形涂色。请注意,涂色有顺序要求:为了避免颜料渗漏使颜色混合,一个矩形只能在所有紧靠它上方的矩形涂色后,才能涂色。例如图中矩形 F 必须在 C 和 D 涂色后才能涂色。注意,每一个矩形必须立刻涂满,不能只涂一部分。
写一个程序求一个使 APM 拿起刷子次数最少的涂色方案。注意,如果一把刷子被拿起超过一次,则每一次都必须记入总数中。
输入格式
第一行为矩形的个数 N 。
下面有 N 行描述了 N 个矩形。每个矩形有 5 个整数描述,左上角的 y 坐标和 x 坐标,右下角的 y 坐标和 x 坐标,以及预定颜色。
输出格式
一行一个整数,表示拿起刷子的最少次数。
样例
输入
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
思路
一眼大法师
因为样例太水所以暴力过了
只需要用深搜遍历每条路
若是到了第n次,就更新答案返回
春春的暴力题
代码
#include<bits/stdc++.h>
using namespace std;
int n;
int mins=0x3f3f3f3f;
bool aa[105][105],vis[25];
struct pb{
int zx,zy;
int yx,yy;
int col;
}a[25];
bool sao(int,int,int);
void tu(int);
void mo(int);
void dfs(int,int,int);
int main()
{
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].zx>>a[i].zy>>a[i].yx>>a[i].yy>>a[i].col;
a[i].zx++;
a[i].zy++;
a[i].yx++;
a[i].yy++;
for(int j=a[i].zx+1;j<=a[i].yx;j++){//每一个点初始化为1,与0区别开
for(int k=a[i].zy+1;k<=a[i].yy;k++){//左端点一定要加一因为点可能会重复赋值
aa[k][j]=1;
}
}
}
for(int i=1;i<=n;i++){
if(a[i].zx==1&&!vis[i]){//从第一层开始搜
vis[i]=1;
tu(i);
dfs(i,1,1);
mo(i);
vis[i]=0;//回溯
}
}
cout<<mins;
return 0;
}
bool sao(int y,int b,int e){//扫一遍当前矩形上面一行
for(int i=b+1;i<=e;i++){
if(aa[y][i]){//如果有没涂的就false掉(1代表没涂)
return false;
}
}
return true;
}
void tu(int i){//把这个矩形涂上
for(int k=a[i].zx+1;k<=a[i].yx;k++){
for(int j=a[i].zy+1;j<=a[i].yy;j++){
aa[k][j]=0;
}
}
}
void mo(int i){//抹去颜色
for(int k=a[i].zx+1;k<=a[i].yx;k++){
for(int j=a[i].zy+1;j<=a[i].yy;j++){
aa[k][j]=1;
}
}
}
void dfs(int ago,int k,int s){
if(s>mins){//小小小剪枝,如果当前s比当前找到的最优解还大,直接return
return;
}
if(k==n){
mins=min(mins,s);
return;
}
for(int i=1;i<=n;i++){
if(!vis[i]){
if(sao(a[i].zx,a[i].zy,a[i].yy)){
vis[i]=1;
tu(i);
if(a[i].col!=a[ago].col){//去下一个矩形的时候判断颜色
dfs(i,k+1,s+1);//若更换颜色,s++
}
else{
dfs(i,k+1,s);
}
vis[i]=0;
mo(i);
}
}
}
}
看完后是不是很吃惊,
这么暴力都过了
俺也一样