首页 > 代码库 > 【codevs2495】水叮当的舞步

【codevs2495】水叮当的舞步

题目描述 Description

水叮当得到了一块五颜六色的格子形地毯作为生日礼物,更加特别的是,地毯上格子的颜色还能随着踩踏而改变。
为了讨好她的偶像虹猫,水叮当决定在地毯上跳一支轻盈的舞来卖萌~~~

地毯上的格子有N行N列,每个格子用一个0~5之间的数字代表它的颜色。
水叮当可以随意选择一个0~5之间的颜色,然后轻轻地跳动一步,左上角的格子所在的联通块里的所有格子就会变成她选择的那种颜色。这里连通定义为:两个格子有公共边,并且颜色相同。
由于水叮当是施展轻功来跳舞的,为了不消耗过多的真气,她想知道最少要多少步才能把所有格子的颜色变成一样的。

输入描述 Input Description

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

输出描述 Output Description

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

样例输入 Sample Input

2
0 0
0 0
3
0 1 2
1 1 2
2 2 1
0

样例输出 Sample Output

0
3

 

 

 

【题解】

A*+迭代加深搜索

搜索题中的经典。

 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<ctime> 7 #include<algorithm> 8 using namespace std; 9 const int dx[5]={1,0,-1,0};10 const int dy[5]={0,1,0,-1};11 int n,depth,ans,used[10],map[10][10],flag[10][10];12 inline int read()13 {14     int x=0,f=1;  char ch=getchar();15     while(!isdigit(ch))  {if(ch==-)  f=-1;  ch=getchar();}16     while(isdigit(ch))  {x=x*10+ch-0;  ch=getchar();}17     return x*f;18 }19 void dfs(int x,int y,int col)20 {21     flag[x][y]=1;22     for(int i=0;i<4;i++)23     {24         int xx=x+dx[i],yy=y+dy[i];25         if(xx<1||xx>n||yy<1||yy>n||flag[xx][yy]==1)  continue;26         flag[xx][yy]=2;27         if(map[xx][yy]==col)   dfs(xx,yy,col);28     }29 }30 int get()31 {32     int t=0;  33     memset(used,0,sizeof(used));34     for(int i=1;i<=n;i++)35         for(int j=1;j<=n;j++)36             if(!used[map[i][j]]&&flag[i][j]!=1)37             {38                 used[map[i][j]]=1;39                 t++;40             }41     return t;42 }43 int fill(int x)44 {45     int t=0;46     for(int i=1;i<=n;i++)47         for(int j=1;j<=n;j++)48             if(flag[i][j]==2&&map[i][j]==x)49             {50                 t++;  51                 dfs(i,j,x);52             }53     return t;54 }55 void search(int k)56 {57     int v=get();58     if(!v)  ans=1;  59     if(v+k>depth||ans)  return;60     int temp[10][10];61     for(int i=0;i<=5;i++)62     {63         memcpy(temp,flag,sizeof(flag));64         if(fill(i))  search(k+1);65         memcpy(flag,temp,sizeof(flag));66     }67 }68 int main()69 {70     while(1)71     {72         ans=0;  depth=0;  n=read();73         if(n==0)  break;74         for(int i=1;i<=n;i++)75             for(int j=1;j<=n;j++)76                 map[i][j]=read();77         memset(flag,0,sizeof(flag));78         dfs(1,1,map[1][1]);    79         while(1)  {search(0);  if(ans)  break;  depth++;}80         printf("%d\n",depth);81     }82     return 0;83 }

 

 

【codevs2495】水叮当的舞步