Description
大意:给定一个n×n的矩阵,每格用一个0~5的数字代表颜色,每次操作可以将左上角联通快里所有格子染成一种颜色,问至少多
少步才能把所有格子变成相同的颜色
每个测试点包含多组数据。每组数据的第一行是一个整数N,表示地摊上的格子有N行N列。接下来一个N*N的矩阵,矩阵中的每个
数都在0~5之间,描述了每个格子的颜色。N=0代表输入的结束。
Output
对于每组数据,输出一个整数,表示最少步数。
2
0 0
0 0
3
0 1 2
1 1 2
2 2 1
0
Sample Output
0
3
Solution
IDA*。。。估价函数是“除左上角外剩下的颜色数目”,听起来很弱,但就是快。。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| #include<cstdio> #include<cstring> #include<algorithm> #define ll long long #define N 10 using namespace std; ll T,n,dx[4]={0,0,1,-1},dy[4]={1,-1,0,0},mark[N][N],a[N][N],flag; void dfs1(ll x,ll y,ll color){ mark[x][y]=1; for (ll i=0;i<4;i++) if ((x+dx[i])&&(y+dy[i])&&x+dx[i]<=n&&y+dy[i]<=n&&mark[x+dx[i]][y+dy[i]]!=1){ mark[x+dx[i]][y+dy[i]]=2; if (a[x+dx[i]][y+dy[i]]==color) dfs1(x+dx[i],y+dy[i],color); } } ll tot(){ ll t[6],ans=0; memset(t,0,sizeof t); for (ll i=1;i<=n;i++) for (ll j=1;j<=n;j++) if (mark[i][j]!=1) t[a[i][j]]=1; for (ll i=0;i<=5;i++) ans+=t[i]; return ans; } ll change(ll x){ ll ans=0; for (ll i=1;i<=n;i++) for (ll j=1;j<=n;j++) if (mark[i][j]==2&&a[i][j]==x) dfs1(i,j,x),ans++; return ans; } void dfs2(ll x,ll exp){ ll t=tot(),tmp[N][N];; if (!t) flag=1; if (flag||exp<x+t) return; for (ll i=0;i<=5;i++){ memcpy(tmp,mark,sizeof mark); if (change(i)) dfs2(x+1,exp); memcpy(mark,tmp,sizeof tmp); } } int main(){ scanf("%d",&n); while(n){ memset(a,0,sizeof a); memset(mark,0,sizeof mark); for (ll i=1;i<=n;i++) for (ll j=1;j<=n;j++) scanf("%d",&a[i][j]); dfs1(1,1,a[1][1]); for (ll i=0;i<=n*n;i++){ flag=0; dfs2(0,i); if (flag) {printf("%d\n",i); break;} } scanf("%d",&n); } }
|