zoukankan      html  css  js  c++  java
  • 题解 P1283 【平板涂色】

    P1283 平板涂色

    数据范围也太小了qwq。。适合本萌新暴搜

    小小的剪枝:

    1.用pre预处理出每块矩形上方的矩形,pre[i][0]记录数目(如果数据范围再开大一点,直接1~n枚举判断可能超时qwq)

    2.每次对于可以涂的矩形,颜色相同的直接标记涂上,不同的dfs(而不用全都dfs)

    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n,ans;
    int x[17],y[17],xx[17],yy[17],c[17],pre[17][17];
    bool vis[17];
    inline bool chk(int i) {//检查上方的矩形是否都涂过
    	for (int j=1; j<=pre[i][0]; j++)
    		if (!vis[pre[i][j]])
    			return false;
    	return true;
    }
    inline void dfs(int step,int num,int co) {//step拿起刷子的最少次数,num涂过的矩形数,co当前颜色
    	if (step>=ans) return;
    	for (int i=1; i<=n; i++)//每次把能涂的尽量涂好
    		if (!vis[i] && chk(i) && c[i]==co)
    			vis[i]=1,++num;
    	if (num==n) {
    		if (ans>step) ans=step;
    		return;
    	}
    	for (register int i=1; i<=n; i++)//寻找颜色不同但可以涂的继续dfs
    		if (!vis[i] && chk(i)) dfs(step+1,num,c[i]);
    }
    int main() {
    	scanf("%d",&n),ans=n;
    	for (int i=1; i<=n; i++)
        		scanf("%d%d%d%d%d",&y[i],&x[i],&yy[i],&xx[i],&c[i]);
    	for (int i=1; i<=n; i++)
    		for (int j=1; j<=n; j++)
    			if (i^j && yy[i]==y[j])//如果两块矩形不是同一个,且上下贴合
    				if (x[i]<=x[j] && xx[i]>=xx[j]) {
    					pre[j][pre[j][0]=1]=i;
    					break;//如果上矩形覆盖了下矩形的整条边
    				} else if ((x[i]<=xx[j] && x[i]>=x[j]) || (xx[i]<=xx[j] && xx[i]>=x[j]))//如果覆盖了一部分
    					pre[j][++pre[j][0]]=i;
    
    	for (register int a=1; a<=n ;a++)
    		if (!pre[a][0]) memset(vis,0,sizeof vis),vis[a]=1,dfs(1,1,c[a]);//每次寻找可以涂的开始dfs
    	printf("%d",ans);
    }
    
  • 相关阅读:
    源码阅读笔记 BiLSTM+CRF做NER任务(一)
    leetcode题 寻找两个有序数组的中位数
    动手实现感知机算法,多分类问题
    剪绳子 牛客网-剑指Offer_编程题
    [SCOI2016]妖怪 牛客网的ACM省选题,个人看法,欢迎交流
    BERT 学习笔记
    解决图着色问题 python代码实现
    维吉尼亚密码及程序实现
    迪菲-赫尔曼密钥交换
    分布式系统组件之配置中心
  • 原文地址:https://www.cnblogs.com/Randolph68706/p/11282789.html
Copyright © 2011-2022 走看看