2 0 0 0 0 3 0 1 2 1 1 2 2 2 1 0
很容易就能想到IDA*
不过最开始只想到目前至少要染多少次的剪枝 TLE,看到别人代码注意到当前染色后连通块必须增大,以此剪枝就还是TLE,最后又把vector删了,自己写了个结构体才AC
看来vector还是不敢随意用
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int a[9][9],n,num[6],nn,ans,depth,tmp,pre,rr,cc; int dr[4]={-1,0,1,0},dc[4]={0,1,0,-1}; bool vis[9][9]; struct Node { int r,c; Node(int rr=0,int cc=0) { r=rr,c=cc; } }; struct node { int num; Node a[65]; }; void judge() { int i,j; for(i=0;i<=5;++i) num[i]=0; for(i=0;i<n;++i) for(j=0;j<n;++j) ++num[a[i][j]]; sort(num,num+6); } void bfs(node& change) { int i=0,j,co=a[0][0]; memset(vis,false,sizeof(vis)); vis[0][0]=true; change.a[0].r=change.a[0].c=0; change.num=1; while(i<change.num) { for(j=0;j<4;++j) { if(0<=(rr=change.a[i].r+dr[j])&&rr<n&&0<=(cc=change.a[i].c+dc[j])&&cc<n&&a[rr][cc]==co&&!vis[rr][cc]) { change.a[change.num].r=rr,change.a[change.num].c=cc; ++change.num; vis[rr][cc]=true; } } ++i; } } bool dfs(int step) { judge(); if(num[5]==nn) { ans=step; return true; } int i; tmp=0; for(i=4;i>=0;--i,++tmp) if(num[i]==0) break; if(step+tmp>depth) return false; node change; int col=a[0][0],j; bfs(change); if(change.num<=pre) return false; for(i=0;i<6;++i) { if(col==i) continue; for(j=0;j<change.num;++j) a[change.a[j].r][change.a[j].c]=i; pre=change.num; if(dfs(step+1)) return true; } for(j=0;j<change.num;++j) a[change.a[j].r][change.a[j].c]=col; return false; } int main() { int i,j; while(scanf("%d",&n),n) { nn=n*n; for(i=0;i<n;++i) for(j=0;j<n;++j) scanf("%d",&a[i][j]); depth=0; pre=0; while(!dfs(0)) { ++depth; pre=0; } printf("%d\n",ans); } return 0; }