JZOJ 3422.[NOIP2013模拟] 水叮当的舞步

Time Limits: 1000 ms  Memory Limits: 262144 KB  Detailed Limits 

Description

水叮当得到了一块五颜六色的格子形地毯作为生日礼物,更加特别的是,地毯上格子的颜色还能随着踩踏而改变。

为了讨好她的偶像虹猫,水叮当决定在地毯上跳一支轻盈的舞来卖萌~~~

地毯上的格子有N行N列,每个格子用一个0~5之间的数字代表它的颜色。

水叮当可以随意选择一个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

Data Constraint

对于30%的数据,N<=5

对于50%的数据,N<=6

对于70%的数据,N<=7

对于100%的数据,N<=8,每个测试点不多于20组数据。
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 using namespace std;
 5 int    xx[4]={0,0,-1,1};
 6 int    yy[4]={1,-1,0,0};
 7 int    a[10][10],vis[10][10],e[6];
 8 int    n,flag,d;
 9 void color(int x,int y,int col)
10 {
11     vis[x][y]=1;
12     for(int i=0;i<4;i++)
13     {
14         int nx=x+xx[i],ny=y+yy[i];
15         if(nx<1||nx>n||ny<1||ny>n||vis[nx][ny]==1)
16             continue;
17         vis[nx][ny]=2;
18         if(a[nx][ny]==col)
19             color(nx,ny,col);
20     }
21 }
22 int eva(int s)
23 {
24     int cnt=0;
25     memset(e,0,sizeof(e));
26     for(int i=1;i<=n;i++)
27         for(int j=1;j<=n;j++)
28             if(vis[i][j]!=1&&!e[a[i][j]])
29                 e[a[i][j]]=1,cnt++;
30     return(cnt);
31 }
32 bool judge(int col)
33 {
34     int tmp=0;
35     for(int i=1;i<=n;i++)
36         for(int j=1;j<=n;j++)
37             if(a[i][j]==col&&vis[i][j]==2)
38             {
39                 tmp++;
40                 color(i,j,col);
41             }
42     return(tmp>0);
43 }
44 void search(int s)
45 {
46     int tmp=eva(s),t[10][10];
47     if(tmp==0)
48     {
49         flag=1;
50         return;
51     }else if(tmp+s>d)
52         return;
53     for(int i=0;i<=5;i++)
54     {
55         memcpy(t,vis,sizeof(t));
56         if(judge(i))
57             search(s+1);
58         memcpy(vis,t,sizeof(vis));
59         if(flag)
60             return;
61     }
62 }
63 int main()
64 {
65     while(scanf("%d",&n)!=EOF&&n)
66     {
67         flag=0;memset(vis,0,sizeof(vis));
68         for(int i=1;i<=n;i++)
69             for(int j=1;j<=n;j++)
70                 cin>>a[i][j];
71         color(1,1,a[1][1]);
72         for(d=0;d>=0;d++)
73         {
74             search(0);
75             if(flag)
76             {
77                 cout<<d<<endl;
78                 break;
79             }
80         }
81     }
82     return 0;
83 }

猜你喜欢

转载自www.cnblogs.com/anbujingying/p/11297589.html