【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 }

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值