1 条题解
-
0
#include<bits/stdc++.h> using namespace std; int n,dep=0; int v[10][10],a[10][10]; int vis[10]; int dx[4]={1,-1,0,0};//x坐标偏移量。 int dy[4]={0,0,1,-1};//y坐标偏移量。 int get(){//估价函数+判断整张图是否为同一颜色。 memset(vis,0,sizeof(vis)); int ans=0; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(v[i][j]!=1){ vis[a[i][j]]=1;//把出现的标记上。 } } } for(int i=0;i<6;i++){ if(vis[i]==1){ ans++;//统计还有几种颜色。 } } return ans; } void p(int x,int y,int s){ v[x][y]=1; for(int i=0;i<4;i++){ int o1=x+dx[i],o2=y+dy[i]; if(o1<=0||o2<=0||o1>n||o2>n||v[o1][o2]==1){//出界或已访问过。 continue; } if(a[o1][o2]!=s){//和要涂的颜色不一样,但可能接下来会被拓展,所以打标记。 v[o1][o2]=2; continue; } p(o1,o2,s);//涂下一个方块。 } } bool dfs(int de){ int gj=get(); if(gj==0){//只有一种颜色了,成功。 return true; } if(de+gj>dep){//超过能走的步数,返回。 return false; } int bf[10][10];//备份v数组。 for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ bf[i][j]=v[i][j]; } } for(int i=0;i<6;i++){ int f=0;//判断是否能拓展。 for(int j=1;j<=n;j++){ for(int k=1;k<=n;k++){ if(v[j][k]==2&&a[j][k]==i){//在当前颜色与我们要涂的颜色相同时拓展。 p(j,k,i); f=1; } } } if(f==1&&dfs(de+1)){//如果能拓展就尝试。 return true;//dfs成功,一路返回到底。 } for(int i=1;i<=n;i++){//把v数组复原。 for(int j=1;j<=n;j++){ v[i][j]=bf[i][j]; } } } return false; } int main(){ while(1){//多组数据。 cin>>n; if(n==0){ break; } memset(v,0,sizeof(v));//初始化。 for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cin>>a[i][j]; } } p(1,1,a[1][1]);//先把左上角涂一次。 dep=0; while(1){//迭代加深。 if(dfs(0)){//当dfs成功时输出步数。 cout<<dep<<"\n"; break; } dep++; } } return 0; }
- 1
信息
- ID
- 128
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者