Description

大意:给定一个n×n的矩阵,每格用一个0~5的数字代表颜色,每次操作可以将左上角联通快里所有格子染成一种颜色,问至少多
少步才能把所有格子变成相同的颜色 

Input

每个测试点包含多组数据。每组数据的第一行是一个整数N,表示地摊上的格子有N行N列。接下来一个N*N的矩阵,矩阵中的每个
数都在0~5之间,描述了每个格子的颜色。N=0代表输入的结束。 

Output

对于每组数据,输出一个整数,表示最少步数。

Sample Input

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);
}
}

文章目录
  1. 1. Description
  2. 2. Input
  3. 3. Output
  4. 4. Sample Input
  5. 5. Sample Output
  6. 6. Solution