LOJ#10023. 平板涂色【搜索】

题目描述 https://loj.ac/problem/10023
难得我自己一遍A的题,有点小兴奋啦啦啦啦

搜索的时候要分成两部分搜,一部分是跟上个色板颜色一样的色板,这时步数不用加;另一部分就是颜色不一样的色板,这时步数就要加了。
不管是哪种情况,都需要做的是,判断,做标记,更新能涂的地方,最后要回溯。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int x1[20],x2[20],y1[20],y2[20],col[20],n,ans=999999; 
bool fl[20],f[105][105],fg; 
bool jud(int x,int l,int r)
{
	for(int i=l;i<=r;i++)
	  if(f[x][i]==0) return 0;
	return 1;
}
void dfs(int k,int st,int co)
{//    第k个色板 步数 上一色板的颜色 
   if(k==n)
   { 
   	  if(st<ans) ans=st;
	  return;  
   }
   for(int i=1;i<=n;i++)
     if(fl[i]==0&&jud(x1[i],y1[i],y2[i])&&col[i]==co)
	 {
	     fl[i]=1;
		 for(int j=y1[i];j<=y2[i];j++) f[x2[i]][j]=1;
		 dfs(k+1,st,co);
		 fl[i]=0;
		 for(int j=y1[i];j<=y2[i];j++) f[x2[i]][j]=0;
	 }	
   for(int i=1;i<=n;i++)
     if(fl[i]==0&&jud(x1[i],y1[i],y2[i])&&col[i]!=co)
	 {
	     fl[i]=1;
		 for(int j=y1[i];j<=y2[i];j++) f[x2[i]][j]=1;
		 dfs(k+1,st+1,col[i]);
		 fl[i]=0;
		 for(int j=y1[i];j<=y2[i];j++) f[x2[i]][j]=0;
	 }
}
int main()
{ 
   scanf("%d",&n);
   for(int i=1;i<=n;i++) 
     scanf("%d%d%d%d%d",&x1[i],&y1[i],&x2[i],&y2[i],&col[i]);
   for(int i=0;i<=99;i++) f[0][i]=1;
   dfs(0,0,0);
   printf("%d",ans);
   	
 return 0;	
}

猜你喜欢

转载自blog.csdn.net/qq_42920122/article/details/88533884