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

 

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com